[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Where's the best version of Hash#pass and Hash#block?

Phlip

3/9/2009 1:47:00 AM

Rubies:

This snippet shows how to pass or block arbitrary subsets of Hashes, by their keys:

http://snippets.dzone.com/posts...

Those items seem useful, because Hashes are not as set-theoretic as Arrays. I
suspect, for example, one cannot & two Hashes to extract their intersection.

That post is from 2006 - essentially the Neolithic Era!

Where's the best modern version of those methods?

--
Phlip
9 Answers

Trans

3/9/2009 3:07:00 AM

0



On Mar 8, 9:48=A0pm, Phlip <phlip2...@gmail.com> wrote:
> Rubies:
>
> This snippet shows how to pass or block arbitrary subsets of Hashes, by t=
heir keys:
>
> =A0 =A0http://snippets.dzone.com/posts...
>
> Those items seem useful, because Hashes are not as set-theoretic as Array=
s. I
> suspect, for example, one cannot & two Hashes to extract their intersecti=
on.
>
> That post is from 2006 - essentially the Neolithic Era!
>
> Where's the best modern version of those methods?

From Facets:

def slice(*keep_keys)
h =3D {}
keep_keys.each do |key|
h[key] =3D fetch(key)
end
h
end

def except(*less_keys)
slice(*keys - less_keys)
end


T.

Phlip

3/9/2009 3:41:00 AM

0

>> Where's the best modern version of those methods?
>
> From Facets:

Thanks - I guessed as much, but isn't there also another Boost-style library for
Ruby? (Boost is essentially Facets for C++ - a repository of reference
implementations for future Standardization, complete with their implications.)

> def slice(*keep_keys)

It's okay, but...

If I already have an array, I have to splat * it in:

my_hash.slice(*array)

Why doesn't slice do the flatten trick here?

keep_keys = [keep_keys].flatten

--
Phlip
http://www.zerop...

Matthias Reitinger

3/9/2009 7:52:00 AM

0

Phlip wrote:
> Where's the best modern version of those methods?

Here's my shot at it:

class Hash
def pass(*keys)
Hash[select {|k,v| keys.include? k}]
end

def block(*keys)
reject {|k,v| keys.include? k}
end
end

-Matthias
--
Posted via http://www.ruby-....

Matthias Reitinger

3/9/2009 7:59:00 AM

0

Phlip wrote:
>> def slice(*keep_keys)
>
> It's okay, but...
>
> If I already have an array, I have to splat * it in:
>
> my_hash.slice(*array)
>
> Why doesn't slice do the flatten trick here?
>
> keep_keys = [keep_keys].flatten

It would lead to ambiguities if you additionally allowed passing an
array of keys. Consider:

hsh = { [:one, :two] => [1, 2], :one => 1, :two => 2 }
hsh.slice([:one, :two])

Now what should the last line yield? Both { :one => 1, :two => 2 } and
{ [:one, :two] => [1, 2] } would be valid, depending on how you
interpret [:one, :two] (array of keys vs. single key).

-Matthias
--
Posted via http://www.ruby-....

Phlip

3/9/2009 12:22:00 PM

0

Matthias Reitinger wrote:

> Here's my shot at it:
>
> class Hash
> def pass(*keys)
> Hash[select {|k,v| keys.include? k}]
> end
>
> def block(*keys)
> reject {|k,v| keys.include? k}
> end
> end

Dude that's so lean I'm tossing facets and going with it. Tx!

Phlip

3/9/2009 12:25:00 PM

0

Matthias Reitinger wrote:

>> Why doesn't slice do the flatten trick here?
>>
>> keep_keys = [keep_keys].flatten
>
> It would lead to ambiguities if you additionally allowed passing an
> array of keys. Consider:

I had already considered the system that only flattens the first depth, but I
forgot to mention it...

Trans

3/9/2009 1:14:00 PM

0



On Mar 9, 8:23=A0am, Phlip <phlip2...@gmail.com> wrote:
> Matthias Reitinger wrote:
> > Here's my shot at it:
>
> > =A0 class Hash
> > =A0 =A0 def pass(*keys)
> > =A0 =A0 =A0 Hash[select {|k,v| keys.include? k}]
> > =A0 =A0 end
>
> > =A0 =A0 def block(*keys)
> > =A0 =A0 =A0 reject {|k,v| keys.include? k}
> > =A0 =A0 end
> > =A0 end
>
> Dude that's so lean I'm tossing facets and going with it. Tx!

#pass doesn't seem to work, at least not in 1.8.

More importantly, Facets implementation is the way it is b/c it is
fast. Code elegance is nice, but you won't be looking at the code when
you are using it.

user system total real
except 0.150000 0.010000 0.160000 ( 0.155591)
block 8.870000 0.020000 8.890000 ( 8.892466)

T.

Matthias Reitinger

3/9/2009 1:35:00 PM

0

Thomas Sawyer wrote:
> #pass doesn't seem to work, at least not in 1.8.

Oops, my fault. I wasn't aware of the fact that I tested it only with
Ruby 1.8.7 (it works there). With Ruby 1.8.6 it fails miserably.

> More importantly, Facets implementation is the way it is b/c it is
> fast. Code elegance is nice, but you won't be looking at the code when
> you are using it.

I must admit that execution speed wasn't one of my priorities for this
snippet. But your point is very valid--I'd also recommend sticking with
the Facets implementation if speed is of any concern.

-Matthias
--
Posted via http://www.ruby-....

Phlip

3/9/2009 2:38:00 PM

0

> Oops, my fault. I wasn't aware of the fact that I tested it only with
> Ruby 1.8.7 (it works there). With Ruby 1.8.6 it fails miserably.

Take off the Hash[].

>> More importantly, Facets implementation is the way it is b/c it is
>> fast. Code elegance is nice, but you won't be looking at the code when
>> you are using it.
>
> I must admit that execution speed wasn't one of my priorities for this
> snippet. But your point is very valid--I'd also recommend sticking with
> the Facets implementation if speed is of any concern.

I needed to slow down my hacking long enough to install facets on our
pairstations, and achieve buy-in, so I will go with this version first.

Also, it's currently only test-side, so speed is slightly less relevant.