[ 
https://issues.apache.org/jira/browse/GROOVY-7037?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15445582#comment-15445582
 ] 

Paul King edited comment on GROOVY-7037 at 8/29/16 11:23 AM:
-------------------------------------------------------------

In some sense this isn't specific to {{getAt}}. Consider this code:
{code}
import static groovy.test.GroovyAssert.shouldFail

class Test {
  def x(String s, Integer i) { "1:$s $i" }
  def x(String s, Integer... is) { "2:$s $is" }
}

assert new Test().x('a', 1) == '1:a 1'                // (1)
assert new Test().x('b') == '2:b []'                  // (2)
assert new Test().x('c', 2, 3) == '2:c [2, 3]'        // (2)
assert new Test().x('d', 4, 5, 6) == '2:d [4, 5, 6]'  // (2)
assert new Test().x(['e', 7]) == '1:e 7'              // (3)
def ex = shouldFail(IllegalArgumentException) {
  new Test().x(['f', 8, 9])                           // (4)
}
assert ex.message == 'wrong number of arguments'
{code}
Groovy does normal argument matching, giving preference to non-varargs matches 
(1) but matching varargs if needed (2).
Also, if a list argument is provided and no method with a list parameter is 
found, an attempt is made to spread the list which matches if a method having 
the correct number and types of arguments can be found (3). But in the case of 
varargs, with a list argument, then the IllegalArgumentException can occur.

Unfortunately for the shorthand {{getAt}} syntax, the arguments are always 
wrapped in a list, so the chances are higher of seeing this error. So, to "fix" 
this error, we'd either have to make the list spreading logic smarter for all 
methods or do some special hacking for getAt.


was (Author: paulk):
In some sense this isn't specific to {{getAt}}. Consider this code:
{code}
import static groovy.test.GroovyAssert.shouldFail

class Test {
  def x(String s, Integer i) { "1:$s $i" }
  def x(String s, Integer... is) { "2:$s $is" }
}

assert new Test().x('a', 1) == '1:a 1'                // (1)
assert new Test().x('b') == '2:b []'                  // (2)
assert new Test().x('c', 2, 3) == '2:c [2, 3]'        // (2)
assert new Test().x('d', 4, 5, 6) == '2:d [4, 5, 6]'  // (2)
assert new Test().x(['e', 7]) == '1:e 7'              // (3)
def ex = shouldFail(IllegalArgumentException) {
  new Test().x(['f', 8, 9])                           // (4)
}
assert ex.message == 'wrong number of arguments'
{code}
Groovy does normal argument matching, giving preference to non-varargs matches 
(1) but matching varargs if needed (2).
Also, if a list argument is provided and no method with a list parameter is 
found, an attempt is made to spread the list which matches if a method having 
the correct number and types of arguments can be found (3). But in the case of 
varargs, with a list argument, then the IllegalArgumentException can occur.

Unfortunately for the shorthand {{getAt}} syntax, the arguments are always 
wrapped in a list, so the chances are higher of seeing this error..

> getAt as Operator Throws if given Fixed and Variable Arguments
> --------------------------------------------------------------
>
>                 Key: GROOVY-7037
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7037
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.3.6, 2.4.0-beta-2
>         Environment: RHEL 6.5 x64
>            Reporter: Steve Amerige
>            Priority: Minor
>         Attachments: Test.groovy
>
>
> The getAt method for indexing fails when variable arguments are used with [] 
> if any fixed arguments are present.  For example:
> {code}
> class Test
> {
>    def getAt(String s) { return s }
>    def getAt(String s, Integer x) { return "$s $x" }   
>    // def getAt(Object... o) { return o }   // This would succeed
>    def getAt(String s, Object... a) { return "$s $a" }
>    static void main(String[] args)
>    {
>       Test t = new Test()
>       assert t['a'] == 'a'
>       assert t['b', 2] == 'b 2'
>       assert t.getAt('c', 3, true) == 'c [3, true]'
>       assert t['c', 3, true] == 'c [3, true]'   // This throws an exception
>    }
> }
> {code}
> The above produces:
> {noformat}
> Exception thrown
> java.lang.IllegalArgumentException: wrong number of arguments
>       at Test.main(ConsoleScript42:14)
> {noformat}
> Workaround: do not use fixed and variable arguments at the same time and use 
> only variable arguments as in the case shown commented out above: 
> getAt(Object... o).  This is less-than desirable, however, because it 
> restricts the user from using method overloading to separate out 
> distinctly-different logic and forces the user to do runtime checks and 
> implement control structure when using the single varargs method.  In this 
> case, however, the bug severity is mitigated by the fact that the user can 
> explicitly use the "getAt" invocation instead of using the [ ] operator 
> notation.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to