5

我读过 ruby​​ 对象只是我们可以存储实例变量(和类指针)的地方。所以:

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

现在如果我们运行:

p = Person.new(101)

然后我们得到:

#<Person:0x86cf5b8 @age=101>

太好了,正如预期的那样,属性age存储为实例变量。但是,如果我们将模型转换为从 ActiveRecord 继承,情况会有所不同。现在,在实例化一个新的 Person 之后,我们会看到:

# timestamps removed
#<Person id: 1, age: 101 > 

age属性似乎不再是实例变量。那么这里到底发生了什么?

我知道我们可以访问@attributes包含所有属性和值的散列的实例变量,所以我想知道 ActiveRecord 是否可能会修改控制台输出以以这种方式呈现对象属性。

是否可以在不使用 ActiveRecord 的情况下实例化一个 Ruby 对象,其中属性作为属性而不是实例变量保存?

4

3 回答 3

3

是的,您可以扩展一个 ruby​​ 类,include ActiveModel::AttributeMethods以将您的实例变量公开为ActiveModel-like 属性。

有关更多信息,请参阅文档

于 2012-06-07T13:30:54.037 回答
1

正如您在代码中看到的那样,将属性“存储”为实例变量是您自己做的,所以如果您想以任何其他方式保存它们,也取决于您。ruby 为您提供了方便的类方法来定义 getter 和 setter 方法,例如 attr_accessor。

还值得注意的是,如果您从 ActiveRecord::Base 继承,则不应覆盖初始化。

于 2012-06-07T13:37:20.467 回答
0

我想知道 ActiveRecord 是否可能会修改控制台输出以这种方式呈现对象属性。

嗯,有点。负责的方法是inspect它是由 Object以一种方式实现的(emplasis mine):

...显示对象的类名、对象 id 的编码以及实例变量及其值的列表(通过对每个变量调用检查)。

后面还有更多:

用户定义的类应覆盖此方法以提供更好的 obj 表示。

这正是 ActiveRecord 所做的,也是您看到此输出的原因。被覆盖的方法不会列出实例变量,而是显示 AR 属性。

因此,仅仅因为您没有在控制台中看到实例变量并不意味着它不存在!

于 2018-02-20T01:52:23.957 回答