Hi --

On Thu, 21 Jun 2007, Alexander Presber wrote:

> Am 21.06.2007 um 11:20 schrieb Robert Klemme:
>
>> 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?
>
> Sorry for the empty post, to much clicking without thinking.
>
>> The #select in Enumerable can only return a "general" type - in this case 
>> an Array.
>
> I see, but isn't that restating the problem?

I think Robert's point is that nothing other than a general type makes
sense.  For example, if you select from an IO stream, you don't expect
another IO stream.

> Even though "Programming Ruby" states: [snip] Enumerable#reject: returns an 
> array for all elements of enumObj for which block is false (see also 
> Enumerable#find_all) [/snip],
> reject _respects_ the class it acts upon in returning a _hash_, not an array.
> Not so select.
> Do you see the inconsistency?

Hash overrides Enumerable#reject.  I'm not sure why, except possibly
because of the relation between reject and delete_if.

>> Making Enumerable depend on the class is not a good idea IMHO.  Maybe an 
>> implementation using #dup would help though...
>
> Could you please elaborate into that? I do not understand.
>
>> Of course Hash#select could act differently but that a) might hurt duck 
>> typing
>
> I fail to see why, could you give an example?

Anything that depends on the output having array-like behaviors:

selected = enum.select(&select_block).flatten


David

-- 
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
   RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
     & consulting:  Ruby Power and Light, LLC (http://www.rubypal.com)