On Wed, 16 Aug 2006, Trans wrote:

>>    def each(&block)
>>      if block.arity < 2
>>        each_value(&block)
>>      else
>>        each_pair(&block)
>>      end
>>    end
>
> Yes that's much better.
>
> On the other hand, I'm glad you bring this up. Are you actively using
> this call? As you hopefully noticed from the docs, this variation of
> Hash#each comes with a WARNING:
>
>  # WARNING! Use with caution. Methods from other libraries
>  # may depend on the old behavior, expecting a two element
>  # array to be passed into a single block argument.
>
> I'm "abstractly" of the opinion that this alternate definition makes
> more sense, nonetheless it may just be TOO danagerous for practicel use
> b/c of the compatability issue. Would others concur? Or is it safe to
> use in limited circumstance as I have been assuming?

both will cause all sorts of issues.  this fails:

     harp:~ > cat a.rb
     h = {:k => :v}

     h.each{|*a| p a}

     class << h
       def each(&block)
         if block.arity < 2
           each_value(&block)
         else
           each_pair(&block)
         end
       end
     end

     h.each{|*a| p a}


     harp:~ > ruby a.rb
     [[:k, :v]]
     [:v]

it's much trickier than you give credit.  for instance this also fails:

     harp:~ > cat a.rb
     h = {:k => :v}

     h.each{|*a| p a}

     class Hash
       def each *a, &b
         send "each_#{ b.arity == 1 ? 'value' : 'pair' }", &b
       end
     end

     h.each{|*a| p a}

     h.each{|v| p v}


     harp:~ > ruby a.rb
     [[:k, :v]]
     [:k, :v]
     :v



this looks close, but i'll leave to someone else to see how it also might fail:


     harp:~ > cat a.rb
     h = {:k => :v}

     h.each{|*a| p a}

     class Hash
       # cache all original instance methods
       METHODS = Hash.new{|h,k| h[k] = instance_method k}
       instance_methods.each{|m| METHODS[m]}

       def each *a, &b
         b.arity == 1 ? each_value(*a, &b) : METHODS['each'].bind(self).call(*a, &b)
       end
     end

     h.each{|*a| p a}

     h.each{|v| p v}


     harp:~ > ruby a.rb
     [[:k, :v]]
     [[:k, :v]]
     :v



you have to understand your arities if you're going to go that route.  moral:
don't override built-ins ;-)

cheers.

-a
-- 
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama