开发者

Why does String::sub!() change the original of a cloned object in Ruby?

I have a struct in my Ruby code that looks somewhat like this

Parameter = Struct.new(:name, :id, :default_value, :minimum, :maximum)

later, I create an instance of this struct using

freq = Parameter.new('frequency', 15, 1000.0, 20.0, 20000.0)

At some point, I need an exact duplicate of this struct开发者_开发技巧, so I call

newFreq = freq.clone

Then, I change newFreq's name

newFreq.name.sub!('f', 'newF')

Which, miraculously, changes freq.name, too!

A simple assignment like newFreq.name = 'newFrequency' does not change freq.

Is this the way this is supposed to work?

Edit: Is it a good idea to use a class instead of a struct and overload clone to make a deep copy?


newFreq is a shallow copy of freq. That means that each of the references stored inside of newFreq points to the object as the ones stored in freq. You can change where the references point independantly (newFreq.name = newFreq.name.sub 'f','newF'), but if you call a method that mutates the object, both newFreq and freq will be affected.

See also http://en.wikipedia.org/wiki/Object_copy


The Object#clone method performs shallow copy. You need deep copy to get the job done.

Follow this link to learn about deep copy in Ruby.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜