On Jun 21, 5:37 am, [email protected] wrote:
Yes, but making a special case of Hash, as opposed to other
enumerables, is exactly what breaks duck typing. I would actually
prefer to see Hash#reject return an array.
I like having arrays be the “common currency” of select operations. I
don’t think there’s anything that you’re prevented from doing as long
as that’s the case.
David
The inconsistency of return values between Hash#reject vs. Hash#select
has bothered me for a long time. Above all, I’d want this to be
consistent, but unlike you (and I believe like the majority), I’d like
both to return a Hash.
I’m not really sure how duck typing even enters into it as a serious
concern. The blocks given to reject/select are different based on the
Enumerable type. Consider:
irb(main):017:0> %w{red green blue}.select { |elem| elem.length > 4 }
=> [“green”]
irb(main):018:0> {:red => true, :green => true, :blue => true}.select
{ |elem| elem.length > 4 }
(irb):18: warning: multiple values for a block parameter (2 for 1)
from (irb):18
(irb):18: warning: multiple values for a block parameter (2 for 1)
from (irb):18
(irb):18: warning: multiple values for a block parameter (2 for 1)
from (irb):18
=> []
I get an Array from both, which is wonderful if I’m expecting an Array
and I want to flatten the return value or do any other Array-specific
things. The only problem is one array is useless and wrong.
irb(main):019:0> {‘red’ => true, ‘green’ => true, ‘blue’ =>
true}.select { |k,v| k.length > 4 }
=> [[“green”, true]]
So now I’ve selected in a more sensible way. The problem here is I
knew I was selecting from a Hash and wrote the block accordingly,
but now I have this Array of two-element Arrays back.
This is why I use reject with a negated block.