You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by "KARR, DAVID" <dk...@att.com> on 2015/08/13 07:11:26 UTC

Assigning "leftover" args to trailing array, difference between func params and plain assignment

Based on a question I saw on IRC, it appears that the way values are allocated to parameters differs between two cases, where one case is calling a function, and the other is an "inline" assignment.

In other words, comparing these two different cases:

	def foo(Object a, Object[] b) { println("a[${a}] b[${b}]") }

And calling it with:

	foo(1, 2, 3, 4)

And the following case:

	def (int a, int[] b) = [1, 2, 3, 4]                   // Given this ...
	println("a[$a] b[$b]")

Putting this all into a script, this outputs this:

	a[1] b[[2, 3, 4]]
	a[1] b[[2]]

Apparently, the ability to allocate the "rest" of the values to a trailing array parameter works fine for function parameters, but for the other case (what would you call that?), it just puts the first value into the array.

Re: Assigning "leftover" args to trailing array, difference between func params and plain assignment

Posted by Dinko Srkoč <di...@gmail.com>.
On 13 August 2015 at 07:11, KARR, DAVID <dk...@att.com> wrote:
> Based on a question I saw on IRC, it appears that the way values are allocated to parameters differs between two cases, where one case is calling a function, and the other is an "inline" assignment.

I don't think those two cases are equivalent.

>
> In other words, comparing these two different cases:
>
>         def foo(Object a, Object[] b) { println("a[${a}] b[${b}]") }
>
> And calling it with:
>
>         foo(1, 2, 3, 4)

That would be the same as Java's: `void foo(Object a, Object... b) {
/* ... */ }`

>
> And the following case:
>
>         def (int a, int[] b) = [1, 2, 3, 4]                   // Given this ...
>         println("a[$a] b[$b]")

No Java equivalent here ;-)

>
> Putting this all into a script, this outputs this:
>
>         a[1] b[[2, 3, 4]]
>         a[1] b[[2]]
>
> Apparently, the ability to allocate the "rest" of the values to a trailing array parameter works fine for function parameters, but for the other case (what would you call that?), it just puts the first value into the array.

It is called multiple assignment.

As I said above, those two features are unrelated. In the case of
multiple assignment, Groovy takes one value at the time from the right
side and assigns it to the next variable from the left side,
performing type conversions if needed. The process stops when there
are no more variables on the left side. If the right side has fewer
elements than there are variables on the left side, the remaining
variables will be set to `null`. In order for this to work an object
on the right side must have a method `getAt(int)`.

More details about multiple assignment can be found here:
http://docs.groovy-lang.org/docs/latest/html/documentation/#_multiple_assignment

Variable number of arguments are described here:
http://docs.groovy-lang.org/docs/latest/html/documentation/#_varargs

Cheers,
Dinko

Re: Assigning "leftover" args to trailing array, difference between func params and plain assignment

Posted by Jochen Theodorou <bl...@gmx.org>.
Am 13.08.2015 07:11, schrieb KARR, DAVID:
[...]
> 	def (int a, int[] b) = [1, 2, 3, 4]                   // Given this ...
> 	println("a[$a] b[$b]")
>
> Putting this all into a script, this outputs this:
>
> 	a[1] b[[2, 3, 4]]
> 	a[1] b[[2]]

that's multiple assignment we are talking about. It is basically defined 
like this:

for "def (x_0,x_1,...,x_n) = l" we get x_i=l[i] but with type/value 
transformations according to Groovy rules. Or in other words, it is 
equal to:

def x_0 = l[0]
def x_1 = l[1]
...
def x_n = l[n]

I would have to check in detail, but the access l[i] is not done 
directly, it is done by using an iterator from l.

This means in your case "def (int a, int[] b) = [1, 2, 3, 4]" you 
basically have this:

int a = 1
int[] b = 2

Groovy will then wrap the single value of 2, into an array for this 
assignment.

As for rules for length. If the iterator does not provide enough 
elements the assignment will fail with a runtime exception. Additional 
elements from the iterator on the other hand are just ignored.

Frankly it is questionable if Groovy should really support that array 
wrapping for "int[] b = 2", especially since something like "int[] b = 
2,3" is not supported. But well... we have it atm.

bye blackdrag

-- 
Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/