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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-03-09 02:50
(Received via mailing list)
Rubies:

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

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

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?
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Thomas Sawyer (7rans)
on 2009-03-09 04:09
(Received via mailing list)
On Mar 8, 9:48 pm, Phlip <phlip2...@gmail.com> wrote:
>
> Where's the best modern version of those methods?

From Facets:

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

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


T.
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-03-09 04:45
(Received via mailing list)
>> 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
09348009e57e24e10bbc08d925bf69ca?d=identicon&s=25 Matthias Reitinger (reima)
on 2009-03-09 08:53
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
09348009e57e24e10bbc08d925bf69ca?d=identicon&s=25 Matthias Reitinger (reima)
on 2009-03-09 09:01
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
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-03-09 13:25
(Received via mailing list)
Matthias Reitinger wrote:

>   end
Dude that's so lean I'm tossing facets and going with it. Tx!
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-03-09 13:31
(Received via mailing list)
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...
45196398e9685000d195ec626d477f0e?d=identicon&s=25 Thomas Sawyer (7rans)
on 2009-03-09 14:16
(Received via mailing list)
On Mar 9, 8:23 am, Phlip <phlip2...@gmail.com> wrote:
> >     end
> >   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.
09348009e57e24e10bbc08d925bf69ca?d=identicon&s=25 Matthias Reitinger (reima)
on 2009-03-09 14:36
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
Aafa8848c4b764f080b1b31a51eab73d?d=identicon&s=25 Phlip (Guest)
on 2009-03-09 15:40
(Received via mailing list)
> 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.
This topic is locked and can not be replied to.