Chris
Chris

Reputation: 391

Multiple method calling

This just returns the original name.

name = "George"
name.reverse.upcase!
puts(name)

I'm wondering why and if there is any way to do what I tried above.

Upvotes: 0

Views: 90

Answers (3)

the Tin Man
the Tin Man

Reputation: 160551

Perhaps this will help explain what's happening:

name = "George"  # => "George"
name.object_id   # => 70228500576040

object_id is the memory reference for the actual variable, in other words, where it lives as the script is running.

reversed_name = name.reverse  # => "egroeG"
reversed_name.object_id       # => 70228500574980

We can tell that reverse created a new variable because the object_id is different from that of name.

upcased_reversed_name = reversed_name.upcase!  # => "EGROEG"
upcased_reversed_name.object_id                # => 70228500574980

The upcase! method modified the same variable as reversed_name.

If we use upcase instead, the object_id changes because a new version of the variable is created:

upcased_reversed_name = reversed_name.upcase  # => "EGROEG"
upcased_reversed_name.object_id               # => 70228500572960
upcased_reversed_name # => "EGROEG"

The short lesson is you can't assign a ! method result to a variable because it acts on the original variable and changes it in place.

Upvotes: 0

Jeff Price
Jeff Price

Reputation: 3229

The methods you are calling do not affect the calling object. name.reverse will return a new String and leave the original alone. What you want to do is reassign name after your call.

name = George
name = name.reverse.upcase

There is a gotcha here in that bang methods, ending in ! will often modify the object being operated upon. So you could do something like below:

name = George
name.reverse!.upcase!

In general, I would avoid the ! methods unless you have a good reason. The first example of setting "name = " is very clear, easy to read and unambiguous.

Upvotes: 2

Jonah
Jonah

Reputation: 17958

reverse returns a new string. upcase! upcases the string it is called on in-place. You are creating a new reversed string, upcasing that new string, and then never using it again.

If you wanted to reverse and upcase the original string you could name.reverse!.upcase!

Upvotes: 3

Related Questions