groovy

Argument Order Messed Up With Maps

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Not A Bug
  • Affects Version/s: 1.6-beta-1
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Testcase included:
    yes
  • Number of attachments :
    0

Description

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!

Activity

Hide
blackdrag blackdrag added a comment -

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

Show
blackdrag blackdrag added a comment - 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
Hide
Robert Fischer added a comment -

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

Show
Robert Fischer added a comment - Where is this specified/documented? I use Groovy quite a bit, and it came as a total surprise to me.
Hide
Brandon Smith added a comment -

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?

Show
Brandon Smith added a comment - 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?
Hide
blackdrag blackdrag added a comment -

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.

Show
blackdrag blackdrag added a comment - 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.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: