0

I'm trying to get very comfortable with all of the array methods and enumerables in Ruby, but I don't understand why some don't mutate and others do. For instance, is there a difference between:

def double(array)
  array.map {|x| x * 2}
end

and

def double(array)
  return array.map! {|x| x * 2}
end

Also, when I tried to call

 b.select{|x| x.even?} 

where b is an array of integers, it did not change, but

  b = b.select{|x| x.even?} OR
 .delete_if

did seem to mutate it.

Is

a.each do |word|
 word.capitalize!
end

the same as

a.map do |word|
 word.capitalize
end

2 Answers 2

3

As a rule of thumb, ruby methods that end in ! will mutate the value they are called on, and methods without will return a mutated copy.

See here the documentation for map vs map! and capitalize vs capitalize!

Also note that b = b.select{|x| x.even?} is not mutating the list b, but is rather calling b.select to create an entirely new list, and assigning that list to b. Note the difference:

In this, b is the same object, just changed:

$ irb
@irb(main):001:0> b = [1,2,3]
=> [1, 2, 3]
@irb(main):002:0> b.object_id
=> 69853754998860
@irb(main):003:0> b.select!{|x| x.even?}
=> [2]
@irb(main):004:0> b.object_id
=> 69853754998860

But in this, b is now an entirely new object:

$ irb
@irb(main):001:0> b = [1,2,3]
=> [1, 2, 3]
@irb(main):002:0> b.object_id
=> 70171913541500
@irb(main):003:0> b = b.select{|x| x.even?}
=> [2]
@irb(main):004:0> b.object_id
=> 70171913502160
Sign up to request clarification or add additional context in comments.

2 Comments

Typo: 'capitalze!' should be 'capitalize!'. Also, the example is fine, but the select can be made even more concise with: b.select(&:even?)
more concise, yes, but less clear; OP was confused about the nature of the difference between two similarly-named method calls, throwing a new concept like method proccing at them isn't going to do anything but confuse them further. Thanks for the typo catch!
1

is there a difference between:

def double(array) array.map {|x| x * 2} end and

def double(array) return array.map! {|x| x * 2} end

Yes. The first one returns a new array. The second one modifies the original array, and returns it.

Is

a.each do |word| word.capitalize! end the same as

a.map do |word| word.capitalize end

No. The first one modifies the elements in the array, and returns the original array. The second one returns a new array filled with new strings.

Comments

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.