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]]
:v
you have to understand your arities if you're going to go that route. moral:
don't override built-ins 
cheers.
-a
···
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?
--
to foster inner awareness, introspection, and reasoning is more efficient than
meditation and prayer.
- h.h. the 14th dali lama