【问题标题】:What is the conventional way to access instance variables within an object in Ruby?在 Ruby 中访问对象中的实例变量的常规方法是什么?
【发布时间】:2011-01-18 04:46:12
【问题描述】:

考虑以下代码:

class Dog
  attr_accessor :name, :color

  def initialize(name, color)
  end
end

在 Ruby 对象中,约定是直接访问实例变量(即@name = name)还是使用setter/getter 方法(即name = name)?

前者对我来说更清楚,但如果你实现自己的 setter/getter 方法(例如同时增加一个类变量),那么你最终不得不同时使用这两种方法(即@name = name ; color = color)。

Ruby 社区的约定是什么?我应该如何编写我的代码以让其他阅读它的人清楚?

【问题讨论】:

标签: ruby conventions instance-variables


【解决方案1】:

使用name = value 是错误的,因为这会创建一个名为name 的局部变量。您必须使用self.name = value

至于约定,只有当你能保证访问器总是是轻量级的attr_accessors 时,你才能避免使用@name。在所有其他情况下,使用@name 而不是self.name 会违反封装并让自己头疼。您在问题中给出了确切的原因 - 如果 getter/setter 中有额外的逻辑,如果您直接访问实例变量,则必须复制它。

【讨论】:

  • 所以局部变量color的作用域优先于方法color?
  • 是的,那肯定会咬你一口。每隔一段时间,我就会忘记 @ 符号,然后花五分钟思考可能出了什么问题。
  • 我很好奇;你为什么声称使用 self.property_name 会破坏封装?如果设置器中有逻辑,我更愿意使用它而不是到处复制代码。
  • @Ed 我的意思正好相反。我稍微改了一下。
  • 啊,现在这更有意义了;)。 +1
【解决方案2】:

应该是@name。这不仅仅是一个约定。 @ 符号将变量的范围定义为定义它的对象的实例内。

【讨论】:

    【解决方案3】:

    我相信你所做的是最传统的方式。

    实际上 attr_accessor 为 read 和 write 创建了两个实例方法。它创建了 2 个方法,例如:

    def color() #getter
      @color
    end
    

    def color=(color) #setter
      @color = color
    end
    

    像 color = color 这样的东西不起作用,因为如果在赋值的左侧找到颜色,它就会被视为局部变量。不过,您可以使用 self.color = color 。 同样,如果颜色不在任何表达式的左侧,它会正常工作,如下所示:

    def show_color
      puts color
    end
    

    【讨论】:

      猜你喜欢
      • 2017-05-24
      • 2012-10-24
      • 2011-02-05
      • 2014-09-24
      • 2012-08-23
      • 2015-12-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      相关资源
      最近更新 更多