I spend some hours to find an error in a dart program.
At most simple I found something like :
class User{
String name;
User(String name){
name = "user +$name";
}
}
It should have been _name for the internal property, but a developer forgets this rule.
The code gives a null result to:
User u1 = new User("U1");
print(u1.name);
> null
My question is :
I find it strange that the compiler allows reusing the same var name in call parameters and inside the code without any warning.
I think that if some parameter is like here *User(String name) *, the further use of name should be read-only.
Is this a weakness of language?
Have you seen the same PB in other languages?
I can see where you are coming from but this is the same scoping rules as Java (and properly also C#?) and normal behavior for parameters for methods and constructors.
I think that reassign a parameter with another value is bad behavior and you can get the analyzer to detect that with adding the following linter rule to analysis_options.yaml:
linter:
rules:
parameter_assignments
The rule are described here:
http://dart-lang.github.io/linter/lints/parameter_assignments.html
But I can see this rule are not used for constructors which are your case and I would guess that this is a bug to the linter or a case where there should be another rule to detect parameter assignments for constructors. I would therefore suggest you create an issue here: https://github.com/dart-lang/linter/issues
The read only behavior for parameters (both for methods and constructors) can be achieved by using final for each parameter as:
User(final String name) {
name = 'user +$name'; // error: 'name' a final variable can only be set once
}
But that is not really practical in the sense where you want to prevent accidents where the developer forget to do something.
And just for the record, you can assign the name value in the User class by doing this (if you still want the parameter and class variable to have the same name):
class User {
String name;
User(String name) {
this.name = 'user +$name';
}
}
Related
I'm using Groovy 2.4.3 inside of a Grails web application. I have the following Trait/Class hierarchy declared in it:
trait GuidData {
String Guid
}
class Enrollment implements GuidData {
String email
}
When I execute the following code I get the expected results:
Enrollment enrollment = new Enrollment(email: "joe#tester.com", guid: "XXXX")
assert enrollment.properties == ['email':'joe#tester.com', 'guid':'XXXX']
assert enrollment.getProperty("guid") == "XXXX")
Enrollment.getDeclaredField("email") == private java.lang.String Enrollment.email
But when I execute the method:
Enrollment.getDeclaredField("guid")
I get a NoSuchFieldException. If I execute a "getDeclaredMethod()" for the "getEmail" method, I correctly get a java.reflect.Method instance back.
So ... it appears that Groovy properties defined in a trait show as Groovy properties and can be referenced like a property defined within the parent class, but they do NOT reflect as a field with getter/setters in the standard Groovy property pattern. In other words, if the property shows up in the instance call to the getProperties(), I would expect the reflection call to get the Field definition to work as well.
From the Groovy documentation on Traits, specifically on public fields (as Burt noted below, this also applies to properties):
…in order to avoid the diamond problem, field names are remapped in the implementing class…
It goes on:
The name of the field depends on the fully qualified name of the trait. All dots (.) in package are replaced with an underscore (_), and the final name includes a double underscore. So if the type of the field is String, the name of the package is my.package, the name of the trait is Foo and the name of the field is bar, in the implementing class, the public field will appear as: String my_package_Foo__bar.
So for the Enrollment class that implements GuidData, it doesn't have a field named Guid, it has a field named GuidData__Guid (assuming Enrollment is not in a package). That's why you're experiencing the NoSuchFieldException. This should work:
Enrollment.getDeclaredField("GuidData__Guid")
The Enrollment class does have getters/setters String getGuid(), void setGuid(String arg1), and that's how you are able to access it using the regular property accessor or using the regular getter syntax.
I am attempting to create Web API controller in F# which returns objects from Entity Framework. SharpObject and SharpContext are my object and DbContext respectively defined in a c# project.
/// Retrieves values.
[<RoutePrefix("api2/values")>]
type ValuesController() =
inherit ApiController()
let values = [| "value1"; "value2" |]
/// Gets all values.
[<Route("")>]
member x.Get() : IEnumerable<SharpObject> =
use context = new SharpContext()
context.SharpObjects.ToList() :> IEnumerable<SharpObject>
Here is SharpObject with the SerializableAttribute.
[Serializable]
public class SharpObject
{
[Key]
public virtual int Id { get; set; }
public virtual string Description { get; set; }
}
The error that I am getting is this:
The type System.Data.Entity.DynamicProxies.SharpObject_3A697B5C46C0BF76858FEAFC93BFED36DD8D4CA2CEACBB178D2D3C38BB2D2052 was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.
When I de-compile this using ILSpy, it looks like this:
[Route("")]
public IEnumerable<SharpObject> Get()
{
SharpContext context = new SharpContext();
IEnumerable<SharpObject> result;
try
{
result = (IEnumerable<SharpObject>)context.SharpObjects.ToList<SharpObject>();
}
finally
{
IDisposable disposable = context as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
return result;
}
What is the best way to get my list to show through in f#?
This happens because the object that you get from EF is not, in fact, of type SharpObject, but rather of that scarily named type, which inherits from SharpObject. This type is called "proxy" and is dynamically generated by EF in order to provide certain services (such as lazy loading, see below).
Because your action is declared as returning IEnumerable<SharpObject>, the default WebAPI's XML serializer expects to find object of that type, and so rightly complains upon finding an object of different type.
One temporary, bandaid-style fix that you can try is to remove the virtual keywords from your entity (why do you have them there, anyway?). It is the presence of the virtual keywords that causes EF to generate the proxy type. Absent virtual, no proxy will be generated, thus making the XML serializer happy.
This, however, will not work once you extend your model to include navigation properties with lazy loading. Those properties, you must make virtual, otherwise lazy loading won't work.
So the correct fix is not to use the same type for both DB-facing DTO and client-facing DTO. Use different types.
Using the same type for these two purposes may seem "convenient" at first, but this road quickly leads to numerous problems. One of small technical problems you have already discovered. But even absent those, conceptually, you almost never, ever want to just serve up your DB records directly to the untrusted user. Some of possible consequences include security holes, badly factored UI code, badly factored database structure, performance problems, and so on.
Bad idea. Don't do it.
P.S. This doesn't actually have anything to do with F#.
This is a pretty basic problem and I'm pretty sure I'm doing something wrong or making some assumption. Here goes.
I'm writing a Jira plugin, which uses the Velocity template system. I have a list of ResultRow objects where ResultRow is a class with a single member variable: String key:
public class ResultRow {
public String key;
}
I have a list of these ResultRows:
List<ResultRow> rows = new ArrayList<ResultRow>();
ResultRow row = new ResultRow();
row.key = "foo";
rows.add(foo);
Map<String, Object> velocityParams = new HashMap<String, Object>();
velocityParams.put("rows", rows);
return descriptor.getHtml("view", velocityParams);
and I am trying to list these rows in a template with the following:
#foreach ($row in $rows)
<tr><td>$row.key</td></tr>
#end
I want the output to be: foo. Maddeningly, the template system simply prints the literal string "$row.key" instead of the contents of key. To verify that "$row" is indeed an object, I used the template:
#foreach ($row in $rows)
<tr><td>$row</td></tr>
#end
and the result was as expected: com.domain.jira.ResultRow#7933f2c6.
I think maybe I'm missing some requirement for the class. Does it need to be defined in some special way to suggest to Velocity that certain members are usable in templates? Does Jira use some special funky version of Velocity that only works with certain objects?
I guess the answer is you cannot do what I was trying to do. You can call member methods but you can't access member variables, which means you'll need to add getters to your class. (Could've sworn I tried that. Ah well.)
Velocity does not expose fields, only methods. There are ways to change that:
You can create your own Uberspect class that allows access to public fields.
You can wrap the instance with a modified version of Velocity's FieldMethodizer that gives access to non-static fields.
You can add and use an instance of a "tool" class to your context, such as a subclass of VelocityTool's ClassTool.
I have a typed class in actionscript:
public class Cat {
public var id:int;
public var name:String;
}
I am using an instance variable in an mxml component:
<valueobjects:Cat id="selected_cat"/>
In IntelliJ the id for cat is coming up as an error, "invalid integer value", although it will compile without error. This error appears in the IDE when editing the file and lists it as an error at bottom. Does anyone know of any tricks to tell IntelliJ about this class or the property. Or are there any metadata tags to identify the attribute so the mxml parser will be happy?
Thanks in advanced.
Yes, the problem is, that usually id is a String used in markup to set an id of type String. Flex supports that via UIComponent or IMXMLObject. You should not use ValueObjects in the markup, unless the class implements IMXMLObject.
To declare a non-visual object in markup you have to use the fx:declarations tag in Flex 4 and above.
The id property in each mxml tag (whether visual or not) acts as a way to reference this object from the rest of the code.
In other words, its the markup equivalent of this.
var selected_car:Car
So the id has to be a String property always.
In your class you declare the id as an int property which is confusing for the compiler because it doesn't know which one is valid.
If you need to work with your class without changing it, you'll have to create instances using AS and not MXML. If you need to work with mxml (to have binding enabled etc) you'll need to change the property name to something like catID perhaps.
I'm trying to dynamically create domain objects in Grails and encountered the problem that for any property referencing another domain object the metaproperty tells me its type is "java.lang.Object" and not the expected type.
For example:
class PhysicalSiteAssessment {
// site info
Site site
Date sampleDate
Boolean rainLastWeek
String additionalNotes
...
is the beginning of a domain class, which references another domain class "Site".
If I try to dynamically find the property types for this class by using this code (in a service):
String entityName = "PhysicalSiteAssessment"
Class entityClass
try {
entityClass = grailsApplication.getClassForName(entityName)
} catch (Exception e) {
throw new RuntimeException("Failed to load class with name '${entityName}'", e)
}
entityClass.metaClass.getProperties().each() {
println "Property '${it.name}' is of type '${it.type}'"
}
then the result is that it recognizes the Java classes, but not the Grails domain class. The output contains the following lines:
Property 'site' is of type 'class java.lang.Object'
Property 'siteId' is of type 'class java.lang.Object'
Property 'sampleDate' is of type 'class java.util.Date'
Property 'rainLastWeek' is of type 'class java.lang.Boolean'
Property 'additionalNotes' is of type 'class java.lang.String'
The problem is that I would like to use the dynamic lookup to find matching objects, e.g. do a
def targetObjects = propertyClass."findBy${idName}"(idValue)
where the propertyClass is retrieved via introspection, idName is the name of the property to look up (not necessarily the database ID) and idValue is the value to find.
It all ends in:
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: static java.lang.Object.findByCode() is applicable for argument types: (java.lang.String) values: [T04]
Is there a way to find the actual domain class for the property? Or maybe some other solution to the problem of finding an instance of a domain class whose type is not given (only a property name that has the type)?
It works if I use the convention that the type name is the property name capitalized ("site"->"Site") to look up the class via the grailsApplication instance, but I would like to avoid that.
Grails allows you to access some meta-information of your domain model via the GrailsApplication instance. You can look it up that way:
import org.codehaus.groovy.grails.commons.ApplicationHolder
import org.codehaus.groovy.grails.commons.DomainClassArtefactHandler
def grailsApplication = ApplicationHolder.application
def domainDescriptor = grailsApplication.getArtefact(DomainClassArtefactHandler.TYPE, "PhysicalSiteAssessment")
def property = domainDescriptor.getPropertyByName("site")
def type = property.getType()
assert type instanceof Class
API:
GrailsApplication
GrailsDomainClass
GrailsDomainClassProperty
You can use GrailsClassUtils.getPropertyType(clazz, propertyName)
The answer above provided by Siegfried became obsolete somewhere around Grails 2.4. ApplicationHolder is obsolete.
Now, you can get real type names from the domainClass property that every domain class has.
entityClass.domainClass.getProperties().each() {
println "Property '${it.name}' is of type '${it.type}'"
}
Note: this answer is not directly to the question but relates enough IMO.
I was banging my head to the wall, ground and surrounding trees when trying to resolve the "generic type" of a collection association:
class A {
static hasMany = {
bees: B
}
List bees
}
Turned out the easiest and yet sound way was mere (and which I did not try but after 3 hours):
A.getHasMany()['bees']