为什么String :: sub!()会更改Ruby中克隆对象的原始内容?

bas*_*ibe 5 ruby clone string-substitution

我的Ruby代码中有一个结构,看起来有点像这样

Parameter = Struct.new(:name, :id, :default_value, :minimum, :maximum)
Run Code Online (Sandbox Code Playgroud)

之后,我使用创建此结构的实例

freq = Parameter.new('frequency', 15, 1000.0, 20.0, 20000.0)
Run Code Online (Sandbox Code Playgroud)

在某些时候,我需要这个结构的完全重复,所以我打电话

newFreq = freq.clone
Run Code Online (Sandbox Code Playgroud)

然后,我换了newFreq名字

newFreq.name.sub!('f', 'newF')
Run Code Online (Sandbox Code Playgroud)

奇迹般地改变freq.name了!

像一个简单的任务newFreq.name = 'newFrequency'不会改变freq.

这是应该的方式吗?

编辑:使用类而不是结构和重载clone来制作深层副本是一个好主意吗?

Ken*_*oom 10

newFreq是一个浅层的副本freq.这意味着存储在newFreq对象内的每个引用都作为存储在其中的对象freq.您可以更改该引用指向independantly( newFreq.name = newFreq.name.sub 'f','newF'),但如果你调用变异的对象,既是方法newFreqfreq将受到影响.

另见http://en.wikipedia.org/wiki/Object_copy


upr*_*ser 8

Object#clone方法执行浅拷贝.您需要深层复制才能完成工作.

请点击此链接了解Ruby中的深层复制.