在Ruby中,在类的实例方法中,我们使用getter by
foo
我们按照
使用setterself.foo = something
一个不需要self.
而另一个不需要,有没有办法让它们看起来更相似,而不是使用self.foo
之类的东西作为getter,因为它看起来也像冗长。
(更新:请注意,getter和setter可能只是获取或设置一个实例变量,但它们也可能会做很多工作,例如进入数据库并检查是否存在记录,如果没有,则创建它,等)
答案 0 :(得分:10)
由于本地范围优先,当您说foo = something
时,将创建一个本地变量foo
,并为其分配something
的内容。
为了使用getter而你可以编写foo
的原因是因为当Ruby找不到具有该名称的变量时它将在范围内向上移动,并且最终会找到该方法。
如果存在与getter方法同名的局部变量,Ruby将使用其值:
class Foo
attr_accessor :foo
def initialize
@foo = :one
end
def f
foo = :two
foo
end
end
Foo.new.f
# => :two
为了明确表示您想要访问setter,您必须编写self.foo = something
。这将告诉Ruby您希望在foo=
对象上执行self
方法,并将something
作为参数。
答案 1 :(得分:5)
如果您愿意违反约定,可以使用jQuery样式编写setter,使用相同的getter和setter方法,具体取决于它是否有参数:
def foo *args
return @foo if args.empty?
@foo = args.first
end
# => nil
foo
# => nil
foo(:bar) # foo = :bar
# => :bar
foo
# => :bar
答案 2 :(得分:1)
据我所知,Ruby中没有办法解决这个问题。我非常有信心这只是Ruby如何评估表达式。
当给定值时,Ruby将首先检查上下文中是否存在与被调用的局部变量匹配的局部变量。如果有(在您的情况下可能是'foo'),那将是使用的值。如果没有这样的值,那么Ruby将尝试将该值作为方法调用查找(作为调用者进入“self”)。如果查找路径中不存在此类方法,则会引发错误。
在setter中使用“self”的需要是避免Ruby将值设置为局部变量,而缺少使用“self”仅在getter实例中没有相同的局部变量时起作用在该上下文中使用的名称。使用自我可以更明确,更清晰,尽管稍微更加冗长,以避免混淆价值来自何处。