From: Rob Biedenharn Date: 2007-01-21T03:36:58+09:00 Subject: Re: Proper way to either create or append to an array? On Jan 20, 2007, at 1:15 PM, Phrogz wrote: > Robert Klemme wrote: >> Since you're using a Hash the block constructor is the most elegant >> solution IMHO: >> >> def initialize >> @foo = Hash.new {|h,k| h[k]=[]} >> ... >> end > > To be clear for those unfamiliar with this: any time you ask for the > value of a key that doesn't exist, the block will be called (which > creates a new empty array). This means you can never see this > particular Hash has a key, since: > if @foo[ :bar ] > will always succeed, and create a (possibly unwanted) array > instance in > the process. That's only because you're not checking for the presence of a key correctly: >> myhash = Hash.new { |h,k| h[k] = Array.new } => {} >> if myhash[:oops] >> puts "nothing" >> end nothing => nil >> myhash => {:oops=>[]} >> if myhash.has_key? :missing >> puts ":missing contains #{myhash[:missing] * ', '}" >> end => nil >> myhash => {:oops=>[]} If you know that your code isn't using the block initialization, then the first form might be OK. However, the #has_key? will always do what you expect. This is particularly true if the value can be nil or false. -Rob Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com