wow, robert, that makes a lot of sense Thanks !
You're welcome!
now my next question: how would a newbie (like me) know by looking at
the ruby doc that Array.map could actually support 2D arrays in this
fashion?
(or is it that it just becomes "obvious" as one uses Ruby more and
more?!)
I guess the latter. What you see is basically the effect of a combination of features: You're actually not dealing with a 2D Array but with an Array that contains Arrays, or more generally, an Enumerable that contains Enumerables. A true 2D Array would make sure that every row has the same number of elements and similarly for columns, that's why it's not a 2D Array. The other aspect is how yield and assignments work. There is some automatic, err, how would you call that, unrolling?
irb(main):001:0> a,b=1,2
=> [1, 2]
irb(main):002:0> a
=> 1
irb(main):003:0> b
=> 2
irb(main):004:0> a,b=[1,2]
=> [1, 2]
irb(main):005:0> a
=> 1
irb(main):006:0> b
=> 2
So, an Array is automatically assigned element wise you do not need to explicitly provide the splat operator:
irb(main):007:0> a,b=*[1,2]
=> [1, 2]
irb(main):008:0> a
=> 1
irb(main):009:0> b
=> 2
You can do a lot more fancy stuff with this as Ruby actually does pattern matching:
irb(main):001:0> a,b,c=1,[2,3]
=> [1, [2, 3]]
irb(main):002:0> a
=> 1
irb(main):003:0> b
=> [2, 3]
irb(main):004:0> c
=> nil
irb(main):005:0> a,(b,c)=1,[2,3]
=> [1, [2, 3]]
irb(main):006:0> a
=> 1
irb(main):007:0> b
=> 2
irb(main):008:0> c
=> 3
This is often useful when using #inject on a Hash:
$ irb
irb(main):001:0> h={}
=> {}
irb(main):002:0> 10.times { i=rand(10); h[i]=10-i}
=> 10
irb(main):003:0> h
=> {0=>10, 6=>4, 7=>3, 2=>8, 8=>2, 3=>7, 9=>1, 4=>6}
irb(main):004:0> h.size
=> 8
irb(main):005:0> h.inject(0) {|sum,(key,val)| sum + key + val}
=> 80
This is of course a silly example. I chose these values in order to make checking what's going on easier (i.e. summing all keys and values equals h.size * 10).
Kind regards
robert
···
On 14.01.2007 12:49, karthik wrote: