[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[Facet] Hash#each

Daniel Schierbeck

8/15/2006 1:40:00 PM

The current implementation of Hash#each[1]:

# File lib/facets/core/hash/each.rb, line 19
def each(&yld)
case yld.arity
when 0
when 1
each_value{|v| yield(v)}
else
each_pair{|k,v| yld.call(k,v)}
end
self
end

To me it looks like we're creating more Proc objects than necessary.
Would this not suffice?

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


Cheers,
Daniel


[1] <http://facets.rubyforge.org/api/core/classes/Hash.html#M...
13 Answers

Trans

8/15/2006 2:59:00 PM

0


Daniel Schierbeck wrote:
> The current implementation of Hash#each[1]:
>
> # File lib/facets/core/hash/each.rb, line 19
> def each(&yld)
> case yld.arity
> when 0
> when 1
> each_value{|v| yield(v)}
> else
> each_pair{|k,v| yld.call(k,v)}
> end
> self
> end
>
> To me it looks like we're creating more Proc objects than necessary.
> Would this not suffice?
>
> 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?

T.

Ara.T.Howard

8/15/2006 3:20:00 PM

0

phrogz

8/15/2006 3:28:00 PM

0

Is this whole facet just to avoid typing two extra characters in the
case where you don't care about the keys? Using standard Ruby 1.8.4
without facets:

foo = { :name=>"Gavin", :age=>33 }
foo.each{ |_,v| p v }
#=> "Gavin"
#=> 33

James Gray

8/15/2006 3:36:00 PM

0

On Aug 15, 2006, at 10:30 AM, phrogz@gmail.com wrote:

> Is this whole facet just to avoid typing two extra characters in the
> case where you don't care about the keys? Using standard Ruby 1.8.4
> without facets:
>
> foo = { :name=>"Gavin", :age=>33 }
> foo.each{ |_,v| p v }
> #=> "Gavin"
> #=> 33

And why the heck wouldn't we just use each_value() there?! ;)

James Edward Gray II

Daniel Schierbeck

8/15/2006 3:41:00 PM

0

Trans wrote:
> 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?

No, I'm not using it, I'm just reading through some of the Facets source
code :)

As Ara pointed out, this may not even work as expected, so perhaps it
would be better to remove it all together.


P.S. I've made a few suggestions on the Facets wiki

Cheers,
Daniel

Trans

8/15/2006 3:44:00 PM

0


ara.t.howard@noaa.gov wrote:

> both will cause all sorts of issues. this fails:

I'm not following how it fails? I may be missing something but it seems
to do what I'd expect:

irb(main):002:0> h.each { |*v| p v }
[[:b, 2]]
[[:a, 1]]
=> {:b=>2, :a=>1}
irb(main):003:0> require 'facet/hash/each'
=> true
irb(main):004:0> h.each { |*v| p v }
[:b, 2]
[:a, 1]
=> {:b=>2, :a=>1}

It's not that is that it's doing something differnet than Ruby normally
does --that's the whole idea. This is an alternate definition to
Hash#each. (See my next post for the why of it all).

T.

Trans

8/15/2006 3:54:00 PM

0


phrogz@gmail.com wrote:
> Is this whole facet just to avoid typing two extra characters in the
> case where you don't care about the keys? Using standard Ruby 1.8.4
> without facets:
>
> foo = { :name=>"Gavin", :age=>33 }
> foo.each{ |_,v| p v }
> #=> "Gavin"
> #=> 33

Actually an interesting question. This is one of the earliest facets in
the library. It came out of a discussion with David Black, Matz and
others about Polymorphic behavior between Array and Hash. If we
considered a Hash's key analogous to an Array's index than one case see
how this definition of #each supports that "meshing", eg.

x = [ :a, :b ]
x.each { |v| p v }
x = { 1 => :a, 2 => :b }
x.each { |v| p v }

See how both array and the hash produce the same result wihtout haveing
to alter the #each statments. You can't currently do that. So this
hash#each method was created more as an "idealistic" expirement of this
concept, then for practical applicaiton --which explain why it
overrides #each vs. using each_value.

I still think it has merit, but as an extension it does have the
potential of breaking other code. So I probably should get rid of it
--and I've known it. But I've sort of left it there as a reminder of
this interesting topic --and indeed it worked! ;-)

T.

ts

8/15/2006 3:54:00 PM

0

>>>>> "T" == Trans <transfire@gmail.com> writes:

T> irb(main):002:0> h.each { |*v| p v }
T> [[:b, 2]]
T> [[:a, 1]]

svg% /usr/bin/ruby -ve '{:a => 1, :b => 2}.each {|*v| p v}'
ruby 1.8.4 (2005-12-24) [i486-linux]
[[:a, 1]]
[[:b, 2]]
svg%


T> irb(main):003:0> require 'facet/hash/each'
T> => true
T> irb(main):004:0> h.each { |*v| p v }
T> [:b, 2]
T> [:a, 1]

svg% ./ruby -ve '{:a => 1, :b => 2}.each {|*v| p v}'
ruby 1.6.8 (2002-12-24) [i686-linux]
[:a, 1]
[:b, 2]
svg%


Guy Decoux

Trans

8/15/2006 4:01:00 PM

0


Daniel Schierbeck wrote:
> Trans wrote:
> > 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?
>
> No, I'm not using it, I'm just reading through some of the Facets source
> code :)
>
> As Ara pointed out, this may not even work as expected, so perhaps it
> would be better to remove it all together.
>
>
> P.S. I've made a few suggestions on the Facets wiki

Thanks I'll have a look!

T.

P.S. Sorry for all my typos --I'm so bad about that. I really need to
learn to slow down and review more.

Ara.T.Howard

8/15/2006 4:13:00 PM

0