From: Robert Dober Date: 2009-06-23T04:31:38+09:00 Subject: Re: map shall not return an Enumerator ( was re guru help ) On Mon, Jun 22, 2009 at 9:13 PM, David A. Black wrote: > Hi -- > > On Tue, 23 Jun 2009, Robert Dober wrote: > >> On Mon, Jun 22, 2009 at 2:52 PM, Brian Candler wrote: >>> >>> Robert Dober wrote: >>> That I dislike very much. What you want is to run a 'join' operation on >>> *each member* of the collection, but that looks like running a .map.join >>> on the *whole* collection. From that point of view, >>> >>>  coll.map { |c| c.join(",") } >>> >>> expresses very clearly what you're doing. >> >> I agree with you, that this is confusing at first sight, but actually >> coll.map.join instead of coll.join does not make any sense at all. >> My corollary is: >> Any method sent to map makes only sense to be sent to the elements of >> the collection and not >> to the collection itself because that would make map a NOP. > > You don't send a message to map, though. map is a method; messages go > to objects. Methods can be provided with code blocks, but that's part > of the method call. Once the next dot appears, the method call is over > and the message goes to the resulting object. You are very harsh with me, I believed this was clear in the context ;) > >> I believe that the confusion arises from the fact that map returns an >> Enumerator and that just seems quite flawed at second thought (or is >> this third thought ;). >> >> Why the heck does map return an Enumerator? If I wanted that I surely >> would have called to_enum ! > > I can't think of any real use case for map returning an enumerator. > It's true that you can do: > >  array.map.with_index {|e,i| ... } > > but that's because enumerators have a with_index method (one of the > very few methods they have that aren't from Enumerable). So you'd be > able to do that no matter how you got the enumerator. yeah this is an edge case, but why should I do map.with_index when I mean to_enum.with_index? > > The returning of an enumerator is more useful with certain other > methods. For example: Oh yeah let me be clear I am only speaking about #map. > >  e = array.each_cons(2) > > Now if you iterate over e, you'll get the each_cons(2) behavior. > >> And if the receiver already was an Enumerator I want to call map for >> some purpose too. > > You can do that: > >  array.each_cons(2).map {|one,two| ... } > > or whatever. (Is that what you meant?) No not at all ;) I do not necessarily believe that map should return a Proxy to do magic dot. It really seems people hate it. coll.map should just complain about the missing block, or about the missing message params if one wants to write code like this map( :+, 42 ) But why overload the name? enum.forward( :+, 42) enum.forward.succ enum.forward( :succ ) enum.send_all( :+, 42 ) enum.send_all.succ enum.send_all( :join, ", " ) enum.send_to_elements( :join, "," ) # Wow this is long but very clear, and automatic code completion will do # the rest ;) Ouch this was long :( Robert