好吧,我可以这样做:
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"
答案 0 :(得分:2)
这是默认行为,虽然令人困惑(特别是如果您习惯于OOP区域中的其他语言)。
Ruby中的实例变量在分配给它时开始可用,通常这种情况发生在你班级的initialize
方法中。
class Person
def initialize(name)
@name = name
end
end
在您的示例中,您正在使用attr_accessor
,这个神奇的方法会为属性名称生成一个getter和一个setter。创建了Person#name
和Person#name=
方法,该方法会覆盖您的“内联”实例变量(这就是您的第一个示例正常工作而第二个示例无效的原因)。
因此,编写预期行为的正确方法是使用initialize
方法。
class Person
def initialize(name)
@name = name
end
def greeting
"Hello, #{@name}"
end
end
经过一番搜索后我发现this awesome answer,所有代表都应该回答这个问题。
答案 1 :(得分: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"