1

When I apply the upcase! method I get:

a="hello"
a.upcase!
a # Shows "HELLO"

But in this other case:

b="hello"
b[0].upcase!
b[0]  # Shows h
b # Shows hello

I don't understand why the upcase! applied to b[0] doesn't have any efect.

alexandresaiz
  • 2,678
  • 7
  • 29
  • 40
Carlos Rojas
  • 95
  • 2
  • 6

2 Answers2

3

b[0] returns a new String every time. Check out the object id:

b = 'hello'
# => "hello"
b[0].object_id
# => 1640520
b[0].object_id
# => 25290780
b[0].object_id
# => 24940620
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
1

When you are selecting an individual character in a string, you're not referencing the specific character, you're calling a accessor/mutator function which performs the evaluation:

2.0.0-p643 :001 > hello = "ruby"
 => "ruby" 
2.0.0-p643 :002 > hello[0] = "R"
 => "R" 
2.0.0-p643 :003 > hello
 => "Ruby" 

In the case when you run a dangerous method, the value is requested by the accessor, then it's manipulated and the new variable is updated, but because there is no longer a connection between the character and the string, it will not update the reference.

2.0.0-p643 :004 > hello = "ruby"
 => "ruby" 
2.0.0-p643 :005 > hello[0].upcase!
 => "R" 
2.0.0-p643 :006 > hello
 => "ruby" 
bashaus
  • 1,614
  • 1
  • 17
  • 33