why does this throw an exception?
messageSource.getMessage('UserService.msg.forgot.unknown', ["test#mail.com"], null)
unless I do this...
def Object[] args = ["test#mail.com"]
messageSource.getMessage('UserService.msg.forgot.unknown', args, null)
Because ["test#mail.com"] evaluates to an ArrayList, not an array:
groovy:000> o = ["asdf"]
===> [asdf]
groovy:000> o.getClass()
===> class java.util.ArrayList
OTOH your declaration creates an array of Objects:
groovy:000> Object[] args = ["asdf"]
===> [Ljava.lang.Object;#14e113b
and the method you're calling needs an array. You can create an array using as:
Object[] args = ["asdf"] as Object[]
The Groovy creators made a point of making higher-level data structures like lists idiomatic, while arrays are present for interoperability with Java.
In his interview in Coders at Work Guy Steele talks about choices made in designing a language:
"There's this Huffman encoding problem. If you make something concise,
something is going to have to be more verbose as a consequence. So in
designing a language, one of the things you think about is, 'What are
the things I want to make very easy to say and very easy to get
right?' But with the understanding that, having used up characters or
symbols for that purpose, you're going to have to make something else
a little bit harder to say."
It certainly looks like Groovy made lists more concise, with the side effect that arrays became more verbose.
Nathan has already (correctly) explained the reason for this behavior at the language level. I just want to move one abstraction level up: Why are you using Spring's MessageSource directly, in the first place? In Grails there is a message tag, that wraps the message source:
g.message(code: 'UserService.msg.forgot.unknown', args: ["test#mail.com"])
Related
In Grails you can declare a controller action like this:
def create(Integer foo, Integer bar) {
}
And if your HTTP request has parameters named foo and bar with values that can be converted to an Integer, the parameters will be assigned these values. I'm wondering how Grails can do this, because my understanding is that at the JVM bytecode level, a method's formal parameter names are not available. Is this witchcraft or am I misunderstanding something?
Basically what happens is that there's an AST transform that adds a new method with no args and the same name. This new method has logic in it to do the data binding based on the declared types of your "real" method, and then call your method. That's why the types are required (otherwise there's no way to do a conversion) and why you cannot have method overloads.
The inability to have overloaded methods is easy to work around though. Say you wanted an action
def foo(String bar)
and another
def foo(String bar, Integer wahoo)
In this scenario just keep the 2nd method and check to see if wahoo is null.
It's also important to use object parameter types and not primitives. If you use int/long/boolean/etc. and there is no provided parameter, you would get a NPE (since zero is not an acceptable conversion from null for numbers, and either is false for booleans).
You can get a decent sense for what's going on if you decompile the class using JD-GUI or another decompiler.
The fact that Grails controllers are Groovy classes helps quite a lot. Looking through the source code for controllers you can see where it makes heavy use of AST transformations, in particular the MethodNode. So, before it becomes bytecode the "witchcraft" is done. :)
The problem is whether an instance method should in anyway alter the object that contains the method or should it return a new instance? I'm new to F# and the concept of full mmutability that is suggested for F#.
Just using psuedo code for now unless I need to be more specific.
First thought is just add the message to the message list on the object:
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
_messages.Add(message)
Second is to construct a new list that joins the old list and the new message. Then I would create a new instance altogther and send back.
class Something
ctr(messages)
_messages.Add(messages)
AddMessage(message)
newMessageList = _messages.Join(message)
return new Something(newMessageList)
Am I overthinking immutability?
In my opinion, the answer depends on your requirements. The immutable style is probably more idiomatic, and would be a sensible default. However, one nice thing about F# is that you can choose what to do based on your needs; there's nothing inherently wrong with code that uses mutation. Here are some things to consider:
Sometimes the mutable approach leads to better performance, particularly when used in a single-threaded context (but make sure to measure realistic scenarios to be sure!)
Sometimes the immutable approach lends itself better to use in multi-threaded scenarios
Sometimes you want to interface with libraries that are easier to use with imperitave code (e.g. an API taking a System.Action<_>).
Are you working on a team? If so, are they experienced C# developers? Experienced F# developers? What kind of code would they find easiest to read (perhaps the mutable style)? What kind of code will you find easiest to maintain (probably the immutable style)?
Are you just doing this as an exercise? Then practicing the immutable style may be worthwhile.
Stepping back even further, there are a few other points to consider:
Do you really even need an instance method? Often, using a let-bound function in a module is more idiomatic.
Do you really even need a new nominal type for what you're doing? If it's just a thin wrapper around a list, you might consider just using lists directly.
As you are doing "class based" programming which is one of the way (rather unfortunate) to do object oriented programming, you would be doing in place state modification rather than returning a new state (as that's what would be expected when you are doing OO).
In case you really want to go towards immutability then I would suggest you need to use more FP concepts like Modules, Functions (not methods which have you have in class based programming), recursive data types etc.
My answer is way too general and the appropriate answer lies in the fact that how this class of your will fit in the big picture of your application design.
I'm using an interpreter for my domain specific language rather than a compiler (despite the performance). I'm struggling to understand some of the concepts though:
Suppose I have a DSL (in XML style) for a game so that developers can make building objects easily:
<building>
<name> hotel </name>
<capacity> 10 </capacity>
</building>
The DSL script is parsed, then what happens?
Does it execute an existing method for creating a new building? As I understand it does not simply transform the DSL into a lower level language (as this would then need to be compiled).
Could someone please describe what an interpreter would do with the resulting parsed tree?
Thank you for your help.
Much depends on your specific application details. For example, are name and capacity required? I'm going to give a fairly generic answer, which might be a bit overkill.
Assumptions:
All nested properties are optional
There are many nested properties, possibly of varying depth
This invites 2 ideas: structuring your interpreter as a recursive descent parser and using some sort of builder for your objects. In your specific example, you'd have a BuildingBuilder that looks something like (in Java):
public class BuildingBuilder {
public BuildingBuilder() { ... }
public BuildingBuilder setName(String name) { ... return this; }
public BuildingBuilder setCapacity(int capacity) { ... return this; }
...
public Building build() { ... }
}
Now, when your parser encounters a building element, use the BuildingBuilder to build a building. Then add that object to whatever context the DSL applies to (city.addBuilding(building)).
Note that if the name and capacity are exhaustive and are always required, you can just create a building by passing the two parameters directly. You can also construct the building and set the properties directly as encountered instead of using the builder (the Builder Pattern is nice when you have many properties and said properties are both immutable and optional).
If this is in a non-object-oriented context, you'll end up implementing some sort of buildBuilding function that takes the current context and the inner xml of the building element. Effectively, you are building a recursive descent parser by hand with an xml library providing the actual parsing of individual elements.
However you implement it, you will probably appreciate having a direct semantic mapping between xml elements in your DSL and methods/objects in your interpreter.
This is a question for the generic collection gurus.
I'm shocked to find that TList does not override equals. Take a look at this example:
list1:=TList<String>.Create;
list2:=TList<String>.Create;
list1.Add('Test');
list2.Add('Test');
Result:=list1.Equals(list2);
"Result" is false, even though the two Lists contain the same data. It is using the default equals() (which just compares the two references for equality).
Looking at the code, it looks like the same is true for all the other generic collection types too.
Is this right, or am I missing something??
It seems like a big problem if trying to use TLists in practice. How do I get around this? Do I create my own TBetterList that extends TList and overrides equals to do something useful?
Or will I run into further complications with Delphi generics...... ?
[edit: I have one answer so far, with a lot of upvotes, but it doesn't really tell me what I want to know. I'll try to rephrase the question]
In Java, I can do this:
List<Person> list1=new ArrayList<Person>();
List<Person> list2=new ArrayList<Person>();
list1.add(person1);
list2.add(person1);
boolean result=list1.equals(list2);
result will be true. I don't have to subclass anything, it just works.
How can I do the equivalent in Delphi?
If I write the same code in Delphi, result will end up false.
If there is a solution that only works with TObjects but not Strings or Integers then that would be very useful too.
Generics aren't directly relevant to the crux of this question: The choice of what constitutes a valid base implementation of an Equals() test is entirely arbitrary. The current implementation of TList.Equals() is at least consistent will (I think) all other similar base classes in the VCL, and by similar I don't just mean collection or generic classes.
For example, TPersistent.Equals() also does a simple reference comparison - it does not compare values of any published properties, which would arguably be the semantic equivalent of the type of equality test you have in mind for TList.
You talk about extending TBetterList and doing something useful in the derived class as if it is a burdensome obligation placed on you, but that is the very essence of Object Oriented software development.
The base classes in the core framework provide things that are by definition of general utility. What you consider to be a valid implementation for Equals() may differ significantly from someone else's needs (or indeed within your own projects from one class derived from that base class to another).
So yes, it is then up to you to implement an extension to the provided base class that will in turn provide a new base class that is useful to you specifically.
But this is not a problem.
It is an opportunity.
:)
You will assuredly run into further problems with generics however, and not just in Delphi. ;)
What it boils down to is this:
In Java (and .NET languages) all types descend from Object. In Delphi integers, strings, etc. do not descend from TObject. They are native types and have no class definition.
The implications of this difference are sometimes subtle. In the case of generic collections Java has the luxury of assuming that any type will have a Equals method. So writing the default implementation of Equals is a simple matter of iterating through both lists and calling the Equals method on each object.
From AbstractList definition in Java 6 Open JDK:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator e2 = ((List) o).listIterator();
while(e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return !(e1.hasNext() || e2.hasNext());
}
As you can see the default implementation isn't really all that deep a comparison after all. You would still be overriding Equals for comparison of more complex objects.
In Delphi since the type of T cannot be guaranteed to be an object this default implementation of Equals just won't work. So Delphi's developers, having no alternative left overriding TObject.Equals to the application developer.
I looked around and found a solution in DeHL (an open source Delphi library). DeHL has a Collections library, with its own alternative List implementation. After asking the developer about this, the ability to compare generic TLists was added to the current unstable version of DeHL.
So this code will now give me the results I'm looking for (in Delphi):
list1:=TList<Person>.Create([Person.Create('Test')]);
list2:=TList<Person>.Create([Person.Create('Test')]);
PersonsEqual:=list1.Equals(list2); // equals true
It works for all types, including String and Integer types
stringList1:=TList<string>.Create(['Test']);
stringList2:=TList<string>.Create(['Test']);
StringsEqual:=stringList1.Equals(stringList2); // also equals true
Sweet!
You will need to check out the latest unstable version of DeHL (r497) to get this working. The current stable release (0.8.4) has the same behaviour as the standard Delphi TList.
Be warned, this is a recent change and may not make it into the final API of DeHL (I certainly hope it does).
So perhaps I will use DeHL instead of the standard Delphi collections? Which is a shame, as I prefer using standard platform libraries whenever I can. I will look further into DeHL.
In Groovy types are optional so you can use either:
String foo = "foo"
foo.noSuchMethod()
or
def foo = "foo"
foo.noSuchMethod()
I assumed that the first example would generate a compile-time error, whereas the second would only fail at runtime. However, this doesn't appear to be the case. In my experience, a compile-time error is generated in neither case.
Am I right in assuming then that the only benefit of declaring the type of a reference is as a form of documentation, i.e. to communicate intentions to other programmers. For example, if I write a method such as:
def capitalize(String arg) {
return arg.toUpperCase()
}
This communicates the type of arguments that should be passed to the function much more effectively than:
def capitalize(def arg) {
return arg.toUpperCase()
}
Does the Groovy compiler perform any type-checking when types are specified?
Thanks,
Don
[Edit] Newer versions of Groovy do allow for compile-time static type checking. Code that uses this annotation IS faster than regular run-time Groovy, as many of the dynamic checks are skipped.
As Cesar said, type checking is a run-time process, one of the major reasons that Groovy is slower than Java (not that that's really bad).
You can see why this is, right? Given the dynamic nature of Groovy, it's near-impossible to tell if String has been extended somewhere else in your code to contain a method noSuchMethod(). The same goes for member type-checking, as it's entirely possible to remove a member of one type, and add a member of another type with the same name later in code. It's probably not common, but very possible.
The question is, how much type checking do you really need? You're calling the method, you really should know what arguments it takes, or if the method actually exists. Using compile-time checking to save you the time of looking it up isn't a core usefulness of the compiler.
In Groovy, type checking is done dynamically at runtime. The benefits of variables with type is that you can be sure that it contains the value you expect them to have, otherwise you get a runtime exception that you can catch and do whatever you need to do to handle the exception.
Compile time-checking in Groovy is close to impossible for types. Your example of
String foo = "foo"
foo.noSuchMethod()
Would work beautifully given that previously an instruction was executed along the lines of
String.metaClass.noSuchMethod { -> println "Yes there is such a method"}
One reason you might specify a type is to allow an IDE to help you.
def foo
foo.[ctrl-space]
... won't help you very much
List foo
foo.[ctrl-space]
... might (depending on the IDE) give you a choice of List's methods. Of course, a method that's not one of the choices might be a valid one to use, for the reasons given in other answers.
There are other automated software maintenance operations that benefit from clues about types. For example, refactoring.