From: Robert Klemme Date: 2012-05-01T06:10:04+09:00 Subject: Re: Question about array of hashes On Mon, Apr 30, 2012 at 10:52 PM, Ralph Shnelvar wrote: > I'm looking at  Page 39 of Why's (poignant) Guide to Ruby ( http://www.rubyinside.com/media/poignant-guide.pdf ) and I see > > [:shape => 'sock', :fabric => 'cashmere'] + > [:shape => 'mouse', :fabric => 'calico'] + > [:shape => 'eggroll', :fabric => 'chenille'] > > The result of this is (irb 1.9.2) > > irb(main):001:0> kitty_toys = > irb(main):002:0* [:shape => 'sock', :fabric => 'cashmere'] + > irb(main):003:0* [:shape => 'mouse', :fabric => 'calico'] + > irb(main):004:0* [:shape => 'eggroll', :fabric => 'chenille'] > => [{:shape=>"sock", :fabric=>"cashmere"}, {:shape=>"mouse", :fabric=>"calico"}, {:shape=>"eggroll", :fabric=>"chenille"}] > irb(main):024:0> kitty_toys.size > => 3 > > That is, it is an array of 3 hashes > > But the lexically similar Similar but not identical. > irb(main):001:0> x= > irb(main):002:0* [1, :fabric => 'cashmere'] + > irb(main):003:0* [2, :fabric => 'calico'] + > irb(main):004:0* [3, :fabric => 'chenille'] > => [1, {:fabric=>"cashmere"}, 2, {:fabric=>"calico"}, 3, {:fabric=>"chenille"}] > irb(main):005:0> x.size > => 6 > > produces what is to me a surprisingly different result. Why are you surprised that a different input gives a different output? > Clearly, ruby has flattened things for x and yet ... it seems to have kept the hashes together for kitty_toys No, it hasn't flattened anything. Note what you have: irb(main):007:0> [1, :fabric => 'cashmere'] => [1, {:fabric=>"cashmere"}] This is an Array with a Fixnum and a Hash. And Array#+ creates a new Array with the content of both arguments concatenated: irb(main):010:0> [1,2] + [4,5] => [1, 2, 4, 5] > I would have expected > > irb(main):006:0> y = [[1, {:fabric=>"cashmere"}], [2, {:fabric=>"calico"}], [3, {:fabric=>"chenille"}]] > => [[1, {:fabric=>"cashmere"}], [2, {:fabric=>"calico"}], [3, {:fabric=>"chenille"}]] > irb(main):007:0> y.size > => 3 I am not sure why you expect that. No nested Arrays are created. > In fact, the more I stare at it, the more I think that the correct syntax should be > > doggy_toys = > [{:shape => 'sock', :fabric => 'cashmere'}] + > [{:shape => 'mouse', :fabric => 'calico'}] + > [{:shape => 'eggroll', :fabric => 'chenille'}] > > Why is the kitty_toys syntax even legal? It's Ruby's way to be nice to the user. You can also use this for method arguments: irb(main):008:0> p(:foo => 1, :bar => 2) {:foo=>1, :bar=>2} => {:foo=>1, :bar=>2} And there are even Keyword arguments, which are translated to a Hash as well: irb(main):009:0> p(foo: 3, bar: 4) {:foo=>3, :bar=>4} => {:foo=>3, :bar=>4} > I see that using the new 1.9 syntax for creating hash tables also works the same way. Exactly. > irb(main):018:0> birdy_toys = > irb(main):019:0* [shape:'sock', fabric:'cashmere'] + > irb(main):020:0* [shape:'mouse', fabric:'calico'] + > irb(main):021:0* [shape:'eggroll', fabric:'chenille'] > => [{:shape=>"sock", :fabric=>"cashmere"}, {:shape=>"mouse", :fabric=>"calico"}, {:shape=>"eggroll", :fabric=>"chenille"}] > irb(main):022:0> doggy_toys == birdy_toys > => true > > So what are the rules for "implied hash table"?  Where would I find that documented? I am sure "The Well-Grounded Rubyist" covers this. Section 9.3, I believe. http://www.amazon.com/dp/1933988657 Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/