Ruby集:创建实例变量不会克隆集

时间:2014-07-03 12:53:10

标签: ruby set

正如人们所料,当使用基本数据类型时,Ruby似乎在将变量分配给实例变量时创建变量的副本。换句话说,@name类中的Person未指向name

class Person
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

name = "Michael"
p = Person.new(name)
name = "Peter"
puts p.name
=> "Michael"

如果你对套装做同样的事情,这就不再适用了。实例变量@family指向family,对family的所有更改都会影响@family

require 'set'

class Family
  attr_reader :people

  def initialize(people)
    @people = people
  end
end

people = Set.new ['Grandfather', 'Father', 'Mother', 'Son', 'Daughter']
family = Family.new(people)
people << 'Grandmother'
puts family.people.include? 'Grandmother'
=> true

为什么Set表现不同?我如何才能最好地创建一个家庭副本? (例如@family = family.dup)?

1 个答案:

答案 0 :(得分:3)

实际上...

  

Ruby在将变量赋值给实例变量

时似乎创建了变量的副本

以你的想法不正确。看哪

class Person
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

name = "Michael"
p = Person.new(name)
name << " Jackson"
puts p.name
# "Michael Jackson"

Ruby确实是一种按值传递的语言,但这些值通常是指向对象的指针。执行name = "Peter"不会影响实例变量,因为您只是分配了一个新指针。如果你使用一个就地修改对象的方法(比如<<)你会影响它,因为两个变量都存储一个指向同一个对象的指针。

你说错了,正确的方法是使用dup