#!/usr/local/bin/ruby
class A
attr_accessor :a_fixnum, :a_string, :an_array
def initialize fixnum, string, array
@a_fixnum = fixnum
@a_string = string
@an_array = array
end
end
a = A.new 0, '', []
b = a.clone
p "b.__id__ == a.__id__ #{b.__id__ == a.__id__}"
p "b.a_fixnum.__id__ == a.a_fixnum.__id__ #{b.a_fixnum.__id__ == a.a_fixnum.__id__}"
p "b.a_string.__id__ == a.a_string.__id__ #{b.a_string.__id__ == a.a_string.__id__}"
a.a_fixnum += 1
a.a_string << '2'
a.an_array << 3
p a
p b
结果是:
➜ ~ ./bug_of_ruby.rb
"b.__id__ == a.__id__ false"
"b.a_fixnum.__id__ == a.a_fixnum.__id__ true"
"b.a_string.__id__ == a.a_string.__id__ true"
#<A:0x007ff583079150 @a_fixnum=1, @a_string="2", @an_array=[3]>
#<A:0x007ff583079128 @a_fixnum=0, @a_string="2", @an_array=[3]>
➜ ~
可是我们知道,直接 clone 一个 array 是不会有这样的表现的
[2] pry(main)> a = [1,2,3]
=> [1, 2, 3]
[3] pry(main)> b = a.clone
=> [1, 2, 3]
[4] pry(main)> a.pop
=> 3
[5] pry(main)> b
=> [1, 2, 3]
个人认为这种诡异的行为给编程带来很多隐患,有什么优雅的变法避免吗