我有一堂课,我正在使用Array#shift
实例变量上的实例方法。我以为我制作了实例变量的“副本”,但事实上我没有并且shift
实际上是在改变实例变量。
例如,在我期望得到之前["foo", "bar", "baz"]
两次均给出以下信息:
class Foo
attr_reader :arr
def initialize arr
@arr = arr
end
def some_method
foo = arr
foo.shift
end
end
foo = Foo.new %w(foo bar baz)
p foo.arr #=> ["foo", "bar", "baz"]
foo.some_method
p foo.arr #=> ["bar", "baz"]
result:
["foo", "bar", "baz"]
["bar", "baz"]
但如图所示,我的“副本”根本不是真正的副本。现在,我不确定是否应该将我想要的称为“复制”,“克隆”,“dup”,“深度克隆”,“深度dup”,“冻结克隆”等......
我真的很困惑要搜索什么,并发现了一堆疯狂的尝试来做看起来像“制作数组的副本”的事情。
然后我发现另一个答案从字面上看,一行就解决了我的问题:
class Foo
attr_reader :arr
def initialize arr
@arr = arr
end
def some_method
foo = [].replace arr
foo.shift
end
end
foo = Foo.new %w(foo bar baz)
p foo.arr #=> ["foo", "bar", "baz"]
foo.some_method
p foo.arr #=> ["foo", "bar", "baz"]
output:
["foo", "bar", "baz"]
["foo", "bar", "baz"]
我明白那个Array#replace
是在实例上调用的实例方法Array
这恰好是一个空数组(例如foo = ["cats", "and", "dogs"].replace arr
仍然有效)并且我得到实例变量的“副本”是有道理的@arr
.
但这与以下有何不同:
foo = arr
foo = arr.clone
foo = arr.dup
foo = arr.deep_clone
Marshal.load # something something
# etc...
或者任何其他疯狂的组合dup
and map
and inject
我在SO上看到的?