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


#1

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?


#2

On Mar 8, 9:48 pm, Phlip removed_email_address@domain.invalid 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.


#3

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


#4

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


#5

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

#6

Matthias R. wrote:

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


#7

Matthias R. 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…


#8

Thomas S. 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


#9

On Mar 9, 8:23 am, Phlip removed_email_address@domain.invalid 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.


#10

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.