Newbie question about multiple assignments


#1

irb(main):091:0> a=1
=> 1
irb(main):092:0> b=2
=> 2
irb(main):093:0> a,b=b,a
=> [2, 1]
irb(main):094:0> a=1
=> 1
irb(main):095:0> b=2
=> 2
irb(main):096:0> a, b = b, a = a, b
=> [2, 1, 2] <-- Why?

What is the order for the assignments


#2

To your why, another why: why do you need to use multiple parallel
assignments in one statement? That said, parallel assignments are
somewhat
known to be a rather messy bit of syntax I’m apparently not as savvy
with
as I thought, since I can’t make heads or tails of what is really
happening.

My personal tip woukd be that the assignments are associative
right-to-left, and only the leftmost assignment is evaluated as a
parallel
one.

What probably happens is broken down into simpler statements:

a = a, b # a == [1, 2]
a, b = b, *a # a ==2, b==1

where the return value of the expression is the rvalue.

So the end values are what you expect, just the return value of the
expression isn’t.

Hint: it’s easy to avoid obscure syntax, so do that if possible. Noone
really admires godawful one-liners from hell in code he expects to
understand a week after writing it, even if there is a certain charm to
getting things done with them :wink:

Also, parallel assignment syntax is undergoing certain subtle, but
significant changes that seem to resolve some of the ambiguity - you
might
want to look on one of the webpages that summarize changes in Ruby 1.9.

David V.


#3

Alex wrote:

irb(main):096:0> a, b = b, a = a, b
=> [2, 1, 2] <-- Why?

What is the order for the assignments

Keep in mind, that

a, b = c, d

is just shorthand for

a, b = [c, d]

So, your expression

a, b = b, a = a, b

gets parsed as

a, b = [b, a = a, b]

and thus produces the observed behaviour.

HTH,

Michael


#4

On Thu, 12 Jan 2006 13:39:00 +0100, Michael U.
removed_email_address@domain.invalid wrote:

=> 2

and thus produces the observed behaviour.

HTH,

Michael

That doesn’t seem to explain the return value [2, 1, 2] of the
expression.

David V.


#5

=> 2

and thus produces the observed behaviour.
David V.
Hi List

Just getting up to speed with ruby myself, try reading Davids
explaination
as:

a, b = [b,(a = a), b]

Karl A.


#6

On Thu, 12 Jan 2006 14:06:56 +0100, Karl A.
removed_email_address@domain.invalid wrote:

Not quite, what I had in mind would be this one-liner:

a, b = [b, *[a = [a, b]]]

I have a slight completely unfounded doubt the interpreter would
implicitly associate (a = a) in the middle of the expression.

The results observed in irb ARE however ambiguous with respect to both
of
those possible interpretations.

David V.


#7

David V. wrote:

=> [2, 1]

gets parsed as

a, b = [b, a = a, b]

and thus produces the observed behaviour.

That doesn’t seem to explain the return value [2, 1, 2] of the expression.

Why not? the return value of an assignment is the right hand
side. In this case [2, 1 , 2]. The first and last value there
coming from b, and the middle value is the return value of the
assignment a = a.

Try this:

irb(main):001:0> a, b = [1, 2, 3, 4] # sets a=1 and b=2
=> [1, 2, 3, 4]

irb(main):002:0> a, b = [1, c = 2, 3] # sets a=1, b=2, and c = 2
=> [1, 2, 3]

HTH,

Michael


#8

Hi –

On Thu, 12 Jan 2006, David V. wrote:

irb(main):094:0> a=1
a, b = c, d

That doesn’t seem to explain the return value [2, 1, 2] of the expression.

An assignment expression returns its right-hand side. In this case,
that’s [b, a = a, b]:

a = 1
b = 2
[b, a = a, b] => [2,1,2]

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#9

thanks guys i figured it out
I was trying to see how this things works in ruby just for fun


#10

On Thu, 12 Jan 2006 15:09:01 +0100, removed_email_address@domain.invalid wrote:

Ah well, for some strange reason I thought the parser would check for a
parallel assignment form inside the array constructor as well.
Apparently
not… Right, that example pretty much clears the issue up.

David V.


#11

David V. wrote:

Ah well, for some strange reason I thought the parser would check for a
parallel assignment form inside the array constructor as well.
Apparently not… Right, that example pretty much clears the issue up.

Within method arguments, the “,” gets parsed as an argument separator
not an array separator:

irb(main):094:0> puts( a,b = 1,2 )
1
1
2
=> nil
irb(main):095:0> puts( ( a,b = 1,2 ) )
1
2
=> nil

irb(main):103:0> a,b=1,2
=> [1, 2]
irb(main):104:0> a,b=(b,a=a,b)
=> [1, 2]
irb(main):105:0> a
=> 1
irb(main):106:0> b
=> 2


#12

Hi –

On Fri, 13 Jan 2006, David V. wrote:

David

Ah well, for some strange reason I thought the parser would check for a
parallel assignment form inside the array constructor as well. Apparently
not… Right, that example pretty much clears the issue up.

The thing is, if you’ve got an array [a,b], and you add to it so that
it is [a,b,c=1], the meaning of the “a,b” part doesn’t change; rather,
you’re understood to have added an element. The comma semantics are
different in these different contexts, in other words.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!