From: Brian Candler Date: 2010-07-12T17:41:08+09:00 Subject: Re: hash example Kaye Ng wrote: > Hello. First of all, I'm reading this ebook, > http://www.ruby-doc.org/docs/ProgrammingRuby/ > is it a good book? It is. You're reading the 1st edition, which was written for ruby 1.6. The 2nd edition is for ruby 1.8 and the 3rd edition for ruby 1.9. The 2nd and 3rd editions are pay-for only. If you're using ruby 1.8, the version you're reading will be perfectly adequate. 1.8 was a minor update which in the main added more core classes, like StringIO, without changing much of what was already there. ruby 1.9 is a substantially different language. If you do use 1.9, you'll find a lot of information missing from that book or is simply wrong. (Personally I am sticking with 1.8) > What does Hash.new(0) do and what > is it used for? It's a Hash which returns 0 for non-existent keys. $ irb --simple-prompt >> h = Hash.new(0) => {} >> h[:foo] = 3 => 3 >> h[:foo] => 3 >> h[:bar] => 0 It's useful when counting things to have the value default to 0, since you don't have to worry about nils >> words = %w(the cat sat on the mat) => ["the", "cat", "sat", "on", "the", "mat"] >> count = Hash.new(0) => {} >> words.each { |w| count[w] += 1 } => ["the", "cat", "sat", "on", "the", "mat"] >> count => {"mat"=>1, "cat"=>1, "sat"=>1, "the"=>2, "on"=>1} Try this again with count = {} and you'll see what I mean. >> count = {} => {} >> words.each { |w| count[w] += 1 } NoMethodError: undefined method `+' for nil:NilClass from (irb):10 from (irb):10:in `each' from (irb):10 from :0 Here's one possible solution which doesn't use Hash.new(0) >> words.each { |w| count[w] = (count[w] || 0) + 1 } => ["the", "cat", "sat", "on", "the", "mat"] >> count => {"mat"=>1, "cat"=>1, "sat"=>1, "the"=>2, "on"=>1} -- Posted via http://www.ruby-forum.com/.