# Parallel Assignments and Elegance/Complexity Ratio.

Discussion in 'Ruby' started by Kedar Mhaswade, Jan 11, 2011.

In SICP, I read that "Programs should be written for people to read, and
only incidentally for machines to execute".

While reading David/Matz book, I stumbled upon parallel assignments and
I thought the language was trying to be too flexible (adding complexity,
at least for a newcomer). My head soon started
spinning (when it reached a, (b, (c,d)) = 1, [2, [3, 4]] I was
exhausted).

My experience is recorded here:

Summary is, I should only spend time learning
- x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
- x, y = y, x (# => swap x and y)

I gather that this might be a matter of taste and style, but are other
variants used by community?

Thank you,
Kedar

--
Posted via http://www.ruby-forum.com/.

2. ### Robert KlemmeGuest

On Tue, Jan 11, 2011 at 3:29 PM, Kedar Mhaswade
<> wrote:
> In SICP, I read that "Programs should be written for people to read, and
> only incidentally for machines to execute".
>
> While reading David/Matz book, I stumbled upon parallel assignments and
> I thought the language was trying to be too flexible (adding complexity,
> at least for a newcomer). My head soon started
> spinning (when it reached a, (b, (c,d)) = 1, [2, [3, 4]] I was
> exhausted).
>
> My experience is recorded here:
>
> Summary is, I should only spend time learning
> - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
> - x, y = y, x (# => swap x and y)
>
> I gather that this might be a matter of taste and style, but are other
> variants used by community?

Just today I used

def []=(*idx, val)
index_check(idx)
@data[idx] = val
end

https://gist.github.com/772827

I find the pattern matching _very_ elegant. This also comes in handy
in situations like this:

irb(main):001:0> a = Array.new(10) { [rand(10), rand(10)] }
=> [[2, 3], [7, 8], [4, 0], [4, 6], [5, 2], [9, 9], [4, 2], [8, 5],
[2, 6], [5, 9]]
irb(main):002:0> a.sort {|(a1,a2),(b1,b2)| x = a2 <=> b2; x == 0 ? a1
<=> b1 : x}
=> [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
[5, 9], [9, 9]]

Although in this particular case you could also use

irb(main):004:0> a.sort_by {|arr| arr.reverse}
=> [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
[5, 9], [9, 9]]
irb(main):005:0> a.sort_by {|x, y| [y, x]}
=> [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
[5, 9], [9, 9]]

Generally I'd say I don't use it overly often but when I use it it is
really handy. With #inject it's also useful if you iterate through a
collection of Arrays of known equal length:

irb(main):006:0> a.inject(0) {|s,(x,y)| s + x + y}
=> 100

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme, Jan 11, 2011

Robert Klemme wrote in post #973945:
> On Tue, Jan 11, 2011 at 3:29 PM, Kedar Mhaswade
> <> wrote:
>>

>

>>
>> Summary is, I should only spend time learning
>> - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
>> - x, y = y, x (# => swap x and y)
>>
>> I gather that this might be a matter of taste and style, but are other
>> variants used by community?

>
> Just today I used
>
> def []=(*idx, val)
> index_check(idx)
> @data[idx] = val
> end
>
> https://gist.github.com/772827
>
>
> I find the pattern matching _very_ elegant. This also comes in handy
> in situations like this:

Maybe I am not understanding it, but I thought that elegance is because
of splat operator (which I am sure I like). My gripe is about various
forms of parallel assignment and semantic/syntactic complexity because
of that. Or are you saying that once you say you need splat operator,
all this complexity is inevitable (of course, I can work around it by
not using it, but then how do you all use it?)

-Kedar

>
> irb(main):001:0> a = Array.new(10) { [rand(10), rand(10)] }
> => [[2, 3], [7, 8], [4, 0], [4, 6], [5, 2], [9, 9], [4, 2], [8, 5],
> [2, 6], [5, 9]]
> irb(main):002:0> a.sort {|(a1,a2),(b1,b2)| x = a2 <=> b2; x == 0 ? a1
> <=> b1 : x}
> => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
> [5, 9], [9, 9]]
>
> Although in this particular case you could also use
>
> irb(main):004:0> a.sort_by {|arr| arr.reverse}
> => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
> [5, 9], [9, 9]]
> irb(main):005:0> a.sort_by {|x, y| [y, x]}
> => [[4, 0], [4, 2], [5, 2], [2, 3], [8, 5], [2, 6], [4, 6], [7, 8],
> [5, 9], [9, 9]]
>
> Generally I'd say I don't use it overly often but when I use it it is
> really handy. With #inject it's also useful if you iterate through a
> collection of Arrays of known equal length:
>
> irb(main):006:0> a.inject(0) {|s,(x,y)| s + x + y}
> => 100
>
> Kind regards
>
> robert

--
Posted via http://www.ruby-forum.com/.

4. ### Josh CheekGuest

[Note: parts of this message were removed to make it a legal post.]

On Tue, Jan 11, 2011 at 8:29 AM, Kedar Mhaswade <>wrote:

> In SICP, I read that "Programs should be written for people to read, and
> only incidentally for machines to execute".
>
> While reading David/Matz book, I stumbled upon parallel assignments and
> I thought the language was trying to be too flexible (adding complexity,
> at least for a newcomer). My head soon started
> spinning (when it reached a, (b, (c,d)) = 1, [2, [3, 4]] I was
> exhausted).
>
> My experience is recorded here:
>
>
> Summary is, I should only spend time learning
> - x, y, z = 1, 2, 3 (# => x=1, y=1, z=3), and
> - x, y = y, x (# => swap x and y)
>
> I gather that this might be a matter of taste and style, but are other
> variants used by community?
>
> Thank you,
> Kedar
>
> --
> Posted via http://www.ruby-forum.com/.
>
>

I don't use it very often, but when I do, it usually makes an elegant
solution. I think part of the reason it doesn't seem that way is because you
are playing with it in too sterile of an environment. For example, you rate
"x, (y, (z, a))=[1, [2, [3, 4]]]" as lowest, suggesting it is equivalent to
"x=1;y=2;z=3;a=4" but this is not true. If you are actually assigning with
literals, you would, of course, use the equivalent way, but if your data
comes in as nested arrays, then you can't assign like that, instead you have
to do something like this:

def parallel(values)
x, (y, (z, a))=values
[x,y,z,a]
end
def alternative(values)
x = values.shift
values = values.shift
y = values.shift
values = values.shift
z = values.shift
a = values.shift
[x,y,z,a]
end
parallel [1, [2, [3, 4]]] # => [1, 2, 3, 4]
alternative [1, [2, [3, 4]]] # => [1, 2, 3, 4]

Now, I don't normally store data like that, so I haven't ever done anything
quite that fancy, but I use arrays on the RHS on occasion. It might look
something like this (though I don't normally store my data like this, either
-- it's really hard to think of a decent example!).

\$stdin = DATA
while input = gets
name , num = input.split
puts "#{name.capitalize}'s favourite number is #{num}"
end
__END__
josh 12
bill 42
sally 13
ned 99
clara 1000000

The alternative of
name , num = input.split
is
values = input.split
name = values.shift
num = values

I consider the former to be much more elegant as it avoids a temporary
variable.

Josh Cheek, Jan 11, 2011

> literals, you would, of course, use the equivalent way, but if your data
> comes in as nested arrays, then you can't assign like that, instead you
> have
> to do something like this:
>
> def parallel(values)
> x, (y, (z, a))=values
> [x,y,z,a]
> end
> def alternative(values)
> x = values.shift
> values = values.shift
> y = values.shift
> values = values.shift
> z = values.shift
> a = values.shift
> [x,y,z,a]
> end
> parallel [1, [2, [3, 4]]] # => [1, 2, 3, 4]
> alternative [1, [2, [3, 4]]] # => [1, 2, 3, 4]
>
> Now, I don't normally store data like that, so I haven't ever done
> anything
> quite that fancy, but I use arrays on the RHS on occasion. It might look
> something like this (though I don't normally store my data like this,
> either
> -- it's really hard to think of a decent example!).

Thank you for sharing the use case. In this case, it helps. But like you
said, it seems like an answer in search of a question.

>
> \$stdin = DATA
> while input = gets
> name , num = input.split
> puts "#{name.capitalize}'s favourite number is #{num}"
> end
> ...
>
> The alternative of
> name , num = input.split
> is
> values = input.split
> name = values.shift
> num = values
>
> I consider the former to be much more elegant as it avoids a temporary
> variable.

This however is already covered by me as the first case (with HIGH
elegance rating) since you are expecting the line to contain exactly two
strings (and if it is not so, it's an exceptional situation) and hence
the (expected) number of lvalues = number of rvalues. I do
like/understand such application of parallel assignment.

Thanks, again!

--
Posted via http://www.ruby-forum.com/.

6. ### Josh CheekGuest

[Note: parts of this message were removed to make it a legal post.]

On Tue, Jan 11, 2011 at 2:29 PM, Kedar Mhaswade <>wrote:

> > variable.
> > I consider the former to be much more elegant as it avoids a temporary

> This however is already covered by me as the first case (with HIGH
> elegance rating) since you are expecting the line to contain exactly two
> strings (and if it is not so, it's an exceptional situation) and hence
> the (expected) number of lvalues = number of rvalues. I do
> like/understand such application of parallel assignment.
>
>

Sorry, I don't understand. In this example, the rhs values are contained in
an Array, which you consider low elegance, in your first example the rhs
values are discrete. I don't see how they are the same, I think this is an
instance of your "x, y, z = [1, 2, 3]", which you consider to be low
elegance.

Josh Cheek, Jan 11, 2011

> Sorry, I don't understand. In this example, the rhs values are contained
> in
> an Array, which you consider low elegance, in your first example the rhs
> values are discrete. I don't see how they are the same, I think this is
> an
> instance of your "x, y, z = [1, 2, 3]", which you consider to be low
> elegance.

Ah, you are right. I stand corrected. Thanks.

--
Posted via http://www.ruby-forum.com/.

8. ### Robert KlemmeGuest

On Tue, Jan 11, 2011 at 7:54 PM, Kedar Mhaswade
<> wrote:
> Robert Klemme wrote in post #973945:
>> On Tue, Jan 11, 2011 at 3:29 PM, Kedar Mhaswade
>> <> wrote:
>>>

>>

cecEzOg/edit?hl=3Den#
>>>
>>> Summary is, I should only spend time learning
>>> - x, y, z =3D 1, 2, 3 (# =3D> x=3D1, y=3D1, z=3D3), and
>>> - x, y =3D y, x (# =3D> swap x and y)
>>>
>>> I gather that this might be a matter of taste and style, but are other
>>> variants used by community?

>>
>> Just today I used
>>
>> =A0 def []=3D(*idx, val)
>> =A0 =A0 index_check(idx)
>> =A0 =A0 @data[idx] =3D val
>> =A0 end
>>
>> https://gist.github.com/772827
>>
>>
>> I find the pattern matching _very_ elegant. =A0This also comes in handy
>> in situations like this:

>
> Maybe I am not understanding it, but I thought that elegance is because
> of splat operator (which I am sure I like).

The splat operator is just part of the game as Josh has tried to
demonstrate. The real power comes from pattern matching which will
even work with multiple levels of nesting. And the mechanism is the
same for method and block arguments which gives you one powerful
mechanism usable in several places.

> My gripe is about various
> forms of parallel assignment and semantic/syntactic complexity because
> of that. Or are you saying that once you say you need splat operator,
> all this complexity is inevitable (of course, I can work around it by
> not using it, but then how do you all use it?)

No, I am saying that parallel assignment is just a special case of the
assignment mechanism that is also in effect for method and block
arguments. And while I don't use the fancy variants often (as Josh)
when I use it it yields an elegant solution that would be more
cumbersome without it.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Robert Klemme, Jan 12, 2011
9. ### Colin BartlettGuest

On Tue, Jan 11, 2011 at 3:30 PM, Robert Klemme
<> wrote:
> ... I find the pattern matching _very_ elegant. ... Generally I'd say
> I don't use it overly often but when I use it it is really handy. ...

On Tue, Jan 11, 2011 at 7:58 PM, Josh Cheek <> wrote:
> I don't use it very often, but when I do, it usually makes an
> elegant solution. I think part of the reason it doesn't seem that
> way is because you are playing with it in too sterile of an environment.

That last sentence seems an accurate assessment of why it perhaps
doesn't seem much use to you, and what Josh Cheek and Robert Klemme
say about those situations where they use it seems appropriate,
although I haven't personally used it in those types of situations
because my Ruby use is relatively simple.

On Tue, Jan 11, 2011 at 8:29 PM, Kedar Mhaswade
<> wrote:
> ... This however is already covered by me as the first case (with HIGH
> elegance rating) since you are expecting the line to contain exactly two
> strings ... and hence the (expected) number of lvalues = number of rvalues.
> I do like/understand such application of parallel assignment.

Strangely, that's the situation (number of lvalues == number of
rvalues) when I definitely dislike its use (unless it might be
necessary to ensure all the rvalues are calculated before any
assignment takes place - might side effects make this necessary?), for
two (and a quarter) reasons.

First, whenever I've benchmarked parallel assignment against
individual assignment, I've found the parallel assignment somewhat
slower. The swap is more elegant, but even that seems slower.

Second, parallel assignment can make it difficult to see what is being
assigned to what. In the following, is it instantly obvious what e is
being set to?
# a, b, c, d, e, f, g, h = q, r, s, t, u, v, w, x
If it is instantly obvious, try more l and r values and/or try longer
variable names and/or values and/or split the assignment expression
over multiple lines!

As an actual example, this from Date:
def initialize(ajd=0, of=0, sg=ITALY)
@ajd, @of, @sg = ajd, of, sg
# ...
end
Admittedly it's easy here to see what's being assigned to what, but
even so is that really better than the alternative just below? Is
there a reason for using the parallel assignment in the actual
example, other than aesthetics?
def initialize(ajd=0, of=0, sg=ITALY)
@ajd = ajd; @of = of; @sg = sg
# ...
end

The quarter is the positive side of the negative point of the second,
that explicit individual assignment is easier visually/cognitively
than parallel assignment.

*** benchmarks

require "benchmark"
a = b = c = d = e = f = g = h = nil; x = y = nil
kt = 1_000_000
Benchmark.bm( 22 ) do |bm|
bm.report( "parallel assignment" ) { kt.times{
a, b, c, d, e, f, g, h = 17, 23, 13, 48, 42, 46, 26, 24 } }
bm.report( "individual assignment" ) { kt.times{
a = 17; b = 23; c = 13; d = 48; e = 42; f = 46; g = 26; h = 24 } }
bm.report( "swap elegant" ) { kt.times{
x = 113; y = 355; x, y = y, x } }
bm.report( "swap messy" ) { kt.times{
x = 113; y = 355; z = x; x = y; y = z } }
end

Using Linux, Ruby 1.9.1, but I've had similar results on MS Windows.
user system total real
parallel assignment 0.630000 0.000000 0.630000 ( 0.635576)
individual assignment 0.400000 0.000000 0.400000 ( 0.393652)
swap elegant 0.500000 0.000000 0.500000 ( 0.506171)
swap messy 0.300000 0.000000 0.300000 ( 0.298167)

MS Windows: ruby 1.9.1p430 (2010-08-16 revision 28998) [i386-mingw32]
user system total real
parallel assignment 0.531000 0.000000 0.531000 ( 0.530000)
individual assignment 0.327000 0.000000 0.327000 ( 0.335000)
swap elegant 0.500000 0.000000 0.500000 ( 0.490000)
swap messy 0.296000 0.000000 0.296000 ( 0.300000)

MS Windows: jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
(Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
user system total real
parallel assignment 0.735000 0.000000 0.735000 ( 0.705000)
individual assignment 0.460000 0.000000 0.460000 ( 0.460000)
swap elegant 0.560000 0.000000 0.560000 ( 0.560000)
swap messy 0.425000 0.000000 0.425000 ( 0.425000)

Colin Bartlett, Jan 12, 2011

>> I do like/understand such application of parallel assignment.
>
> Strangely, that's the situation (number of lvalues == number of
> rvalues) when I definitely dislike its use (unless it might be
> necessary to ensure all the rvalues are calculated before any
> assignment takes place - might side effects make this necessary?), for
> two (and a quarter) reasons.

Interesting (yeah, it's a matter of taste).
But when number of variables is <=3, it looks very readable and easily
understandable.

> First, whenever I've benchmarked parallel assignment against
> individual assignment, I've found the parallel assignment somewhat
> slower. The swap is more elegant, but even that seems slower.

That's a good point, but it's judgmental based on how frequently the
code gets called.

> # a, b, c, d, e, f, g, h = q, r, s, t, u, v, w, x
> If it is instantly obvious, try more l and r values and/or try longer
> variable names and/or values and/or split the assignment expression
> over multiple lines!

Well, one can always abuse a feature. I think number of variables should
be <=3, e.g.
a, b, c = q, r ,s
@d, @e, @f = t(a), u(b), v(c) # ...

>
> As an actual example, this from Date:
> def initialize(ajd=0, of=0, sg=ITALY)
> @ajd, @of, @sg = ajd, of, sg
> # ...
> end
> Admittedly it's easy here to see what's being assigned to what, but
> even so is that really better than the alternative just below? Is
> there a reason for using the parallel assignment in the actual
> example, other than aesthetics?
> def initialize(ajd=0, of=0, sg=ITALY)
> @ajd = ajd; @of = of; @sg = sg
> # ...
> end
>
> The quarter is the positive side of the negative point of the second,
> that explicit individual assignment is easier visually/cognitively
> than parallel assignment.

Yeah. And the (others') wisdom suggests that if and when you find a
situation to apply it, it (usually) renders an elegant solution.

-Kedar

--
Posted via http://www.ruby-forum.com/.

11. ### Charles Oliver NutterGuest

On Wed, Jan 12, 2011 at 10:44 AM, Colin Bartlett
<> wrote:
> First, whenever I've benchmarked parallel assignment against
> individual assignment, I've found the parallel assignment somewhat
> slower. The swap is more elegant, but even that seems slower.

Parallel assignment is generally slower than straight-up assignment in
1.9 and JRuby because it stands up a full Ruby Array for the RHS and
result of the entire assignment expression:

~/projects/jruby =E2=9E=94 jruby -e "p((a, b, c =3D 1, 2, 3))"
[1, 2, 3]

As you would expect this is a significant cost compared to just
assigning the values directly. JRuby can improve this when it knows
that the assignment is not being used as an expression:

~/projects/jruby =E2=9E=94 jruby -rbenchmark -e "2.times{ puts
Benchmark.measure { 10000000.times {a,b,c=3D1,2,3} } }"
1.924000 0.000000 1.924000 ( 1.812000)
1.810000 0.000000 1.810000 ( 1.810000)

~/projects/jruby =E2=9E=94 jruby -rbenchmark -e "2.times{ puts
Benchmark.measure { 10000000.times {a,b,c=3D1,2,3; nil} } }"
1.073000 0.000000 1.073000 ( 0.959000)
0.884000 0.000000 0.884000 ( 0.884000)

There are also some implementations that "cheat" (I mean that in the
nicest way possible) and don't bother producing that array return
value at all, and they perform much better on parallel assignment as a
result.

- Charlie

Charles Oliver Nutter, Jan 14, 2011
12. ### Colin BartlettGuest

On Fri, Jan 14, 2011 at 4:41 PM, Charles Oliver Nutter
<> wrote:
> Parallel assignment is generally slower than straight-up assignment in
> 1.9 and JRuby because it stands up a full Ruby Array for the RHS and
> result of the entire assignment expression:

I'd assumed it was something like that. Thanks for the explanation.

> As you would expect this is a significant cost compared to just
> assigning the values directly. JRuby can improve this when it knows
> that the assignment is not being used as an expression:
> ...
> There are also some implementations that "cheat" (I mean that in the
> nicest way possible)

I don't know if you've heard of the English magician Paul Daniels, but
I'm very fond of a phrase he uses to contrast himself with some people
who are, let us say, not self-admitted magicians. "I cheat, but I
cheat honestly".

> and don't bother producing that array return value at all,
> and they perform much better on parallel assignment as a result.

Cheating honestly, I think!

That's interesting, and the "cheating" idea hadn't ocurred to me. From
the benchmarks below (similar to those you quoted; I did actually run
the benchmarks twice, but the runs were very similar, so to avoid
clutter I've only given one run) it seems MRC 1.9.1 is also cheating
honestly if it can.

Now the only thing that's puzzling me is why the MRI 1.9.1 "cheating
honestly" version of parallel assignment seems to be slightly but
clearly faster than the MRI 1.9.1 single assignment!

require "benchmark"
kt = 10_000_000
nn = 1
nn.times{ puts Benchmark.measure { kt.times {a,b,c=1,2,3 } } }
nn.times{ puts Benchmark.measure { kt.times {a,b,c=1,2,3; nil} } }
nn.times{ puts Benchmark.measure { kt.times {a = 1; b = 2; c = 3 } } }

jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
(Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
3.038000 0.000000 3.038000 ( 3.007000)
1.561000 0.000000 1.561000 ( 1.562000)
1.558000 0.000000 1.558000 ( 1.558000)

ruby 1.9.1p430 (2010-08-16 revision 28998) [i386-mingw32]
3.962000 0.000000 3.962000 ( 3.963000)
1.747000 0.000000 1.747000 ( 1.741000)
2.106000 0.000000 2.106000 ( 2.105000)

Colin Bartlett, Jan 14, 2011
13. ### Charles Oliver NutterGuest

On Fri, Jan 14, 2011 at 2:45 PM, Colin Bartlett <> w=
rote:
> Now the only thing that's puzzling me is why the MRI 1.9.1 "cheating
> honestly" version of parallel assignment seems to be slightly but
> clearly faster than the MRI 1.9.1 single assignment!

Yes, that is a bit baffling! I have no explanation for that. As you
can see in JRuby, the times for the non-expression parallel assignment
and the normal assignment are roughly the same.

> require "benchmark"
> kt =3D 10_000_000
> nn =3D 1
> nn.times{ puts Benchmark.measure { kt.times {a,b,c=3D1,2,3 =C2=A0 =C2=A0 =

} } }
> nn.times{ puts Benchmark.measure { kt.times {a,b,c=3D1,2,3; nil} } }
> nn.times{ puts Benchmark.measure { kt.times {a =3D 1; b =3D 2; c =3D 3 } =

} }
>
> jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7)
> =C2=A0(Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
> =C2=A03.038000 =C2=A0 0.000000 =C2=A0 3.038000 ( =C2=A03.007000)
> =C2=A01.561000 =C2=A0 0.000000 =C2=A0 1.561000 ( =C2=A01.562000)
> =C2=A01.558000 =C2=A0 0.000000 =C2=A0 1.558000 ( =C2=A01.558000)

FWIW, you'd get better results here if you ran a couple iterations,
and of course if you specified --server it's significantly better...

~/projects/jruby =E2=9E=94 jruby -v passign.rb
jruby 1.6.0.RC1 (ruby 1.8.7 patchlevel 330) (2011-01-14 da2bb9d) (Java
HotSpot(TM) Client VM 1.6.0_22) [darwin-i386-java]
1.952000 0.000000 1.952000 ( 1.839000)
1.784000 0.000000 1.784000 ( 1.784000)
1.796000 0.000000 1.796000 ( 1.796000)
0.919000 0.000000 0.919000 ( 0.919000)
0.865000 0.000000 0.865000 ( 0.865000)
0.856000 0.000000 0.856000 ( 0.856000)
0.961000 0.000000 0.961000 ( 0.961000)
0.924000 0.000000 0.924000 ( 0.924000)
0.880000 0.000000 0.880000 ( 0.880000)

~/projects/jruby =E2=9E=94 jruby --server -v passign.rb
jruby 1.6.0.RC1 (ruby 1.8.7 patchlevel 330) (2011-01-14 da2bb9d) (Java
HotSpot(TM) Server VM 1.6.0_22) [darwin-i386-java]
1.388000 0.000000 1.388000 ( 1.324000)
1.086000 0.000000 1.086000 ( 1.086000)
1.034000 0.000000 1.034000 ( 1.034000)
0.522000 0.000000 0.522000 ( 0.522000)
0.500000 0.000000 0.500000 ( 0.500000)
0.491000 0.000000 0.491000 ( 0.491000)
0.517000 0.000000 0.517000 ( 0.517000)
0.485000 0.000000 0.485000 ( 0.485000)
0.496000 0.000000 0.496000 ( 0.496000)

Charles Oliver Nutter, Jan 15, 2011
14. ### Joseph LentonGuest

Josh Cheek wrote in post #974019:
> On Tue, Jan 11, 2011 at 8:29 AM, Kedar Mhaswade
> <>wrote:
>
>>
>> Kedar
>>
>> --
>> Posted via http://www.ruby-forum.com/.
>>
>>

> I don't use it very often, but when I do, it usually makes an elegant
> solution. I think part of the reason it doesn't seem that way is because
> you
> are playing with it in too sterile of an environment. For example, you
> rate
> "x, (y, (z, a))=[1, [2, [3, 4]]]" as lowest, suggesting it is equivalent
> to
> "x=1;y=2;z=3;a=4" but this is not true. If you are actually assigning
> with
> literals, you would, of course, use the equivalent way, but if your data
> comes in as nested arrays, then you can't assign like that, instead you
> have
> to do something like this:
>
> def parallel(values)
> x, (y, (z, a))=values
> [x,y,z,a]
> end

x, y, z, a = values.flatten

Which avoids making you look like your writing in LISP.

For small stuff parrallel assignment makes it look elegant, but like any
language feature it can be abused. Although I don't think I've ever
actually found a case where I've wanted to use this. Especially when
most of the time my 'x, y, z and a' variables are unrelated so I don't
want to use them together in the same statement.

--
Posted via http://www.ruby-forum.com/.

Joseph Lenton, Jan 15, 2011

[Note: parts of this message were removed to make it a legal post.]

>
> > def parallel(values)
> > x, (y, (z, a))=values
> > [x,y,z,a]
> > end

>
> Instead you could also do:
>
> x, y, z, a = values.flatten
>
> Which avoids making you look like your writing in LISP.

These two bits of code are not the same thing.

a, (b, c) = [1, [2, [3, 4]]]

a #=> 1
b #=> 2
c #=> [3, 4]

a, b, c = [1, [2, [3, 4]]].flatten

a #=> 1
b #=> 2
c #=> 3

On Sat, Jan 15, 2011 at 11:04 AM, Joseph Lenton <> wrote:

> Josh Cheek wrote in post #974019:
> > On Tue, Jan 11, 2011 at 8:29 AM, Kedar Mhaswade
> > <>wrote:
> >
> >>
> >> Kedar
> >>
> >> --
> >> Posted via http://www.ruby-forum.com/.
> >>
> >>

> > I don't use it very often, but when I do, it usually makes an elegant
> > solution. I think part of the reason it doesn't seem that way is because
> > you
> > are playing with it in too sterile of an environment. For example, you
> > rate
> > "x, (y, (z, a))=[1, [2, [3, 4]]]" as lowest, suggesting it is equivalent
> > to
> > "x=1;y=2;z=3;a=4" but this is not true. If you are actually assigning
> > with
> > literals, you would, of course, use the equivalent way, but if your data
> > comes in as nested arrays, then you can't assign like that, instead you
> > have
> > to do something like this:
> >
> > def parallel(values)
> > x, (y, (z, a))=values
> > [x,y,z,a]
> > end

>
> Instead you could also do:
>
> x, y, z, a = values.flatten
>
> Which avoids making you look like your writing in LISP.
>
> For small stuff parrallel assignment makes it look elegant, but like any
> language feature it can be abused. Although I don't think I've ever
> actually found a case where I've wanted to use this. Especially when
> most of the time my 'x, y, z and a' variables are unrelated so I don't
> want to use them together in the same statement.
>
> --
> Posted via http://www.ruby-forum.com/.
>
>