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)