From: Robert Klemme Date: 2007-06-21T18:20:42+09:00 Subject: Re: Behaviour of Enumerables reject vs. select mixed into Hash On 21.06.2007 11:06, Alexander Presber wrote: >>> Hello everybody, >>> >>> Could you please take a look at the result of the following statements: >>> >>> irb(main):001:0> a = {'foo' => 'bar', 'baz' => 'qux'} >>> => {"baz"=>"qux", "foo"=>"bar"} >>> >>> irb(main):002:0> a.reject{|k,v| k=='foo' } >>> => {"baz"=>"qux"} >>> >>> irb(main):003:0> a.select{|k,v| k=='baz' } >>> => [["baz", "qux"]] >>> >>> The result of the reject statement is clearly sensible: the original >>> hash minus the element with the key 'foo'. >>> But what about select? Shouldn't it return the same hash (instead of >>> an array of key-value pairs)? >> >> I have to concur. I've never liked that. You'd think there'd be some >> way to have Enumerable act in accordance with the class it is >> effecting, rather then dropping to the "LCD" --an array. > > Absolutely. > But the most baffling to me is, that it does not even act > _consistently_, see my original examples. > From a logical point of view (or at least the principle of least > surprise), selecting some elements should be identical > to dropping the others. > > Is there anybody who can explain, why it had to be implemented that way? > Is there any chance of that getting changed in the future? The #select in Enumerable can only return a "general" type - in this case an Array. Making Enumerable depend on the class is not a good idea IMHO. Maybe an implementation using #dup would help though... Of course Hash#select could act differently but that a) might hurt duck typing and b) could break existing code. Note that you can always do something like selected = a_hash.dup.delete_if {|k,v| ... } Kind regards robert