pyRabbit
pyRabbit

Reputation: 828

Why does Ruby change variables outside the scope of a class?

Given the following set of classes:

class Cat
  def initialize(value)
     @value = value
  end

  def speak
     @value.pop()
     puts @value
  end
end

speak = ["Meow","Hiss","Chirp"]

cat = Cat.new(speak)
cat.speak
puts speak

class Dog
  def initialize(value)
     @value = value
  end

  def speak
     @value.sub!("Bark", "Woof")
     puts @value
  end
end

speak = "Bark!"

dog = Dog.new(speak)
dog.speak
puts speak

I would expect the following output to be:

Meow
Hiss
Meow
Hiss
Chirp
Woof!
Bark!

And it is if I provide @value = value.dup but it doesn't feel Ruby'esque

However the output I receive is:

Meow
Hiss
Meow
Hiss
Woof!
Woof!

Is this the expected behavior of Ruby? Should a class be able to modify the argument originator? I know that setting @value = value will return identical object_id's for both @value and value however, if I set @value = 'somethingelse' shouldn't it create a new object instead of changing the original object?

Upvotes: 0

Views: 73

Answers (1)

spickermann
spickermann

Reputation: 106782

Yes, this is expected behavior. And no, if you want to assign a new object then you need to explicitly call dup or clone on the object:

@value = value.dup

Read about the difference between clone and dup in the Ruby docs.

Upvotes: 3

Related Questions