Inconsistency - map/collect not returning enumerator

This seems a bit of an anomoly:

x = [1,2,3].map
x.each { |y| y*2 }
=> [1, 2, 3] # I was expecting [2, 4, 6]

It seems that Array#map and Enumerable#map without a block return just
an Array. However most other Enumerable methods return an Enumerator,
even #each (which is pretty useless, since the Enumerator maps #each to
#each)

RUBY_DESCRIPTION
=> “ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]”

[1,2,3].each
=> #Enumerable::Enumerator:0x7fa4170ea1b0

[1,2,3].map
=> [1, 2, 3]

[1,2,3].collect
=> [1, 2, 3]

class Foo; include Enumerable; def each; yield 1; end; end
=> nil

Foo.new.map
=> [1]

Anybody got a good explanation for this?

On Wed, Jan 27, 2010 at 8:29 AM, Brian C. [email protected]
wrote:

RUBY_DESCRIPTION
=> “ruby 1.8.7 (2009-06-12 patchlevel 174) [x86_64-linux]”

Anybody got a good explanation for this?

Yes. You’re using Ruby 1.8.7, which is, in and of itself, an anomaly :slight_smile:

But this may be to preserve compatibility with Ruby 1.8.6:

RUBY_VERSION
=> “1.8.6”

NOT OK TO CHANGE BEHAVIOR

[1,2,3].map
=> [1, 2, 3]

OK TO ADD BEHAVIOR

[1,2,3].select
LocalJumpError: no block given
from (irb):3:in `select’
from (irb):3

Gregory B. wrote:

But this may be to preserve compatibility with Ruby 1.8.6:

Ah, that’s a good enough reason.

‘ri Array#map’ from 1.8.6 doesn’t mention the possibility that it could
be used without a block, which led me off the scent.

-------------------------------------------------------------- Array#map
array.collect {|item| block } -> an_array
array.map {|item| block } -> an_array

 Invokes _block_ once for each element of _self_. Creates a new
 array containing the values returned by the block. See also
 +Enumerable#collect+.

    a = [ "a", "b", "c", "d" ]
    a.collect {|x| x + "!" }   #=> ["a!", "b!", "c!", "d!"]
    a                          #=> ["a", "b", "c", "d"]