1

好吧,我可以这样做:

class Person
  attr_accessor :name

  def greeting
    "Hello #{@name}"
  end
end

p = Person.new
p.name = 'Dave'
p.greeting  # "Hello Dave"

但是当我决定在类本身中分配属性时它不起作用:

class Person
  attr_accessor :name
  @name = "Dave"    
  def greeting
    "Hello #{@name}"
  end
end

p = Person.new
p.greeting  # "Hello"
4

2 回答 2

2

这是默认行为,尽管令人困惑(尤其是如果您习惯于 OOP 区域中的其他语言)。

Ruby 中的实例变量在分配给它时开始可用,通常这发生在initialize类的方法中。

class Person
  def initialize(name)
    @name = name
  end
end

在您使用的示例中attr_accessor,这种神奇的方法会为属性名称生成一个 getter 和一个 setter。创建了一个 Person#nameand Person#name=, 方法来覆盖您的“内联”实例变量(这就是为什么您的第一个示例有效而第二个示例无效)。

因此,编写预期行为的正确方法是使用initialize方法。

class Person
   def initialize(name)
     @name = name
   end
   def greeting
     "Hello, #{@name}"
   end
end

编辑

经过一番搜索,我找到了这个很棒的答案,所有代表都应该去那个问题。

于 2013-11-10T21:48:49.867 回答
0

Person类视为可以创建单人实例的蓝图。由于并非所有这些人员实例都有名称“Dave”,因此您应该在实例本身上设置此名称。

class Person
  def initialize(name)
    @name = name
  end
  attr_accessor :name

  def greeting
    "Hello #{@name}"
  end
end

david = Person.new("David")
p david.greeting
# => "Hello David"

mike = Person.new("Mike")
p mike.greeting
# => "Hello Mike"
于 2013-11-11T06:39:31.870 回答