25

I'm learning the details of how each works in ruby, and I tried out the following line of code:

p [1,2,3,4,5].each { |element| el }

And the result is an array of

[1,2,3,4,5]

Why is the return value of each the same array? Doesn't each just provide a method for iterating? Or is it just common practice for the each method to return the original value?

3
  • ruby API docs says each {|item| block } → ary so yes each{block} method of Array class returns self Commented Jul 22, 2012 at 0:48
  • 3
    The reason is more of a convenience. It's basically a "free" operation for Ruby to return the original array (otherwise it would return nil). As a bonus it allows you to chain methods to further operate on the array if you want. Commented Jul 22, 2012 at 0:50
  • A small point: if no block is present, [1,2,3].each returns [1,2,3].to_enum (at least in Ruby 2.0). Commented Aug 13, 2013 at 20:23

4 Answers 4

31

Array#each returns the [array] object it was invoked upon: the result of the block is discarded. Thus if there are no icky side-effects to the original array then nothing will have changed.

Perhaps you mean to use map?

p [1,2,3,4,5].map { |i| i*i }
Sign up to request clarification or add additional context in comments.

1 Comment

I wasn't trying to use map, just wondering why the return value was the same array. But you have confirmed that it just returns the same object
7

If you want, for some reason, to suppress the output (for example debugging in console) here is how you can achive that

  [1,2,3,4,5].each do |nr|
    puts nr.inspect
  end;nil

3 Comments

OMG end;nil IS WHAT I'VE BEEN SEARCHING FOR MY WHOLE LIFE!!!
Basically end;nil is the same as just a return nil in the next line after end. The return can be omitted, as ruby methods always return the last statement.
Sure, this makes no sense in real code. But a lot of times the return messes up the console. Like in my example where you wan to see the output.
4

Array#each

The block form of Array#each returns the original Array object. You generally use #each when you want to do something with each element of an array inside the block. For example:

[1, 2, 3, 4, 5].each { |element| puts element }

This will print out each element, but returns the original array. You can verify this with:

array = [1, 2, 3, 4, 5]
array.each { |element| element }.object_id === array.object_id
=> true

Array#map

If you want to return a new array, you want to use Array#map or one of its synonyms. The block form of #map returns a different Array object. For example:

array.object_id
=> 25659920
array.map { |element| element }.object_id
=> 20546920
array.map { |element| element }.object_id === array.object_id
=> false

You will generally want to use #map when you want to operate on a modified version of the original array, while leaving the original unchanged.

Comments

3

All methods return something. Even if it's just a nil object, it returns something.

It may as well return the original object rather than return nil.

1 Comment

Right, I was just expecting it to be Nil, though I should have read the docs a little more carefully.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.