From: Alex Gutteridge Date: 2007-09-03T16:04:51+09:00 Subject: Re: Hash.new with a block? On 3 Sep 2007, at 15:31, 7stud -- wrote: > Robert Klemme wrote: >> $ ruby -e 'h=Hash.new {|h,k| h[k]=[]}; set_trace_func(lambda {|*a| p >> a}); h[1]<<2' >> ["line", "-e", 1, nil, #, false] >> ["c-call", "-e", 1, :[], #, Hash] >> ["c-call", "-e", 1, :default, #, Hash] >> ["c-call", "-e", 1, :call, #, Proc] >> ["line", "-e", 1, nil, #, false] >> ["c-call", "-e", 1, :[]=, #, Hash] >> ["c-return", "-e", 1, :[]=, #, Hash] >> ["c-return", "-e", 1, :call, #, Proc] >> ["c-return", "-e", 1, :default, #, Hash] >> ["c-return", "-e", 1, :[], #, Hash] >> ["c-call", "-e", 1, :<<, #, Array] >> ["c-return", "-e", 1, :<<, #, Array] >> >> I believe there's also some explanation in the documentation. >> > > I don't know what that output means. Each line shows an 'event' occurring in the script. Where event is calling a C method, returning, etc... (see Kernel#set_trace_func). We can summarise what's going on: >> ["line", "-e", 1, nil, #, false] Process new line. >> ["c-call", "-e", 1, :[], #, Hash] Call the C method Hash#[] >> ["c-call", "-e", 1, :default, #, Hash] Call the C method Hash#default. >> ["c-call", "-e", 1, :call, #, Proc] Call the C method Proc#call. This Proc is the one given to Hash.new I guess. Here is the answer to your original question. >> ["line", "-e", 1, nil, #, false] I guess this means we've moved into the Proc >> ["c-call", "-e", 1, :[]=, #, Hash] We call Hash#[] inside our Proc >> ["c-return", "-e", 1, :[]=, #, Hash] >> ["c-return", "-e", 1, :call, #, Proc] >> ["c-return", "-e", 1, :default, #, Hash] >> ["c-return", "-e", 1, :[], #, Hash] Return from each of the previous calls. >> ["c-call", "-e", 1, :<<, #, Array] >> ["c-return", "-e", 1, :<<, #, Array] Push something onto the Array. So short answer: Hash#[] calls Hash#default which in the case of Hash objects with an associated Proc calls the Proc. Alex Gutteridge Bioinformatics Center Kyoto University