在Ruby中,如何在类中编写代码以使getter foo和setter self.foo = ...看起来更相似?

时间:2011-03-20 07:22:23

标签: ruby

在Ruby中,在类的实例方法中,我们使用getter by

foo

我们按照

使用setter
self.foo = something

一个不需要self.而另一个不需要,有没有办法让它们看起来更相似,而不是使用self.foo之类的东西作为getter,因为它看起来也像冗长。

(更新:请注意,getter和setter可能只是获取或设置一个实例变量,但它们也可能会做很多工作,例如进入数据库并检查是否存在记录,如果没有,则创建它,等)

3 个答案:

答案 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实例中没有相同的局部变量时起作用在该上下文中使用的名称。使用自我可以更明确,更清晰,尽管稍微更加冗长,以避免混淆价值来自何处。