Issue Details (XML | Word | Printable)

Key: GROOVY-3006
Type: Bug Bug
Status: Closed Closed
Resolution: Not A Bug
Priority: Major Major
Assignee: Jochen Theodorou
Reporter: Robert Fischer
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
groovy

Argument Order Messed Up With Maps

Created: 18/Aug/08 09:52 PM   Updated: 19/Aug/08 09:01 AM   Resolved: 19/Aug/08 06:29 AM
Return to search
Component/s: None
Affects Version/s: 1.6-beta-1
Fix Version/s: None

Time Tracking:
Not Specified

Testcase included: yes


 Description  « Hide

Running this in the groovyConsole:

void custom(Class cls, Map args) { println cls.name + " " + args }
custom(Integer.class, foo:"Bar!")

Gives me this:

groovy.lang.MissingMethodException: No signature of method: Script3.custom() is applicable for argument types: (java.util.LinkedHashMap, java.lang.Class) values: {[foo:Bar!], class java.lang.Integer}
at Script3.run(Script3:5)

I expect the explosion, but it looks like the types of my arguments are getting swapped around before it explodes. In fact, if I swap the order of the arguments around at the call site –

void custom2(Map args, Class cls) { println cls.name + " " + args }
}
custom2(Integer.class, foo:"Bar!")

That passes w/o a hitch.

I'm not even sure where to start looking to try to fix this, so I don't have a patch to submit. Sorry!



Jochen Theodorou added a comment - 19/Aug/08 06:29 AM

this is not a bug, because we specified a certain order for arguments: First the map, then normal arguments, then varargs. This gives the signature:

def foo(Map m, p1,p2, ..., pn, Object[] q)

if you do a method call
foo(a:1,b:2,c,d:3,e,f,g)
, then groovy will sort the arguments into
foo(a:1,b:2,d:3,c,e,f,g)
. If foo was for example
def foo(Map m, x,y,Object[] z)
then m=[a:1,b:2,d:3], x=c, y=e, z=[f,g]. If you want to use the map somewhere else, then you have to use a real map:
def foo(x,Map m) {1}
def foo(Map m,x) {2}
assert foo(a:1,2) == 2
assert foo(2,a:1) == 2
assert foo([a:1],2) == 2
assert foo(2,[a:1]) == 1
As you can see, no metzhod reordering will happen if you use the normal map


Robert Fischer added a comment - 19/Aug/08 06:43 AM

Where is this specified/documented? I use Groovy quite a bit, and it came as a total surprise to me.


Brandon Smith added a comment - 19/Aug/08 07:34 AM

I noticed this issue is opened against 1.6-beta-1. Is this new functionality introduced in the 1.6 stream? Is this behavior in the 1.5.x stream? If so, when was this behavior introduced?


Jochen Theodorou added a comment - 19/Aug/08 09:01 AM

I searched the documentation and there was nearly nothing. The spec consists more or less out of test cases only, so I thought it might be good to write a bit text: http://groovy.codehaus.org/Extended+Guide+to+Method+Signatures

This functionality is not new in 1.5 or 1.6, Groovy supports maps like this (and the reordering) since early beta stages. So 1.0 had it already.