新手问题 如何理解 Ruby 中的 Attribute 和 Virtual Attribute

springwq · 2013年12月22日 · 最后由 nightire 回复于 2013年12月23日 · 3677 次阅读

attributes 该如何理解,为什么说属性是一种方法?

virtual attributes 又该如何理解?

@nightire 已经说得蛮清楚了

用 js 来举例的话,ember 的 computed property 确实是很好的例子。

Rails 来说的话,有点 presenter 的意思。很多时候你要用一个从已有属性装饰而来的属性,但是又不想存到数据库里

一个相关的最佳实践http://rails-bestpractices.com/posts/4-add-model-virtual-attribute

@nightire 很喜欢一楼这样的回答方式,知其然,知其所以然。

1 楼太赞了, 很多问题都回答的很好.

按照 Ruby User's Guide

An object's instance variables are its attributes, the things that distinguish it from other objects of the same class. It is important to be able to write and read these attributes; doing so requires methods called attribute accessors.

Attributes 是指对象的实例变量。但是我们日常使用中,习惯用 attributes 指代 attributes accessor,也就是实例变量对应的同名 setter/getter 方法,所以也才会有 “Ruby 的属性其实是方法” 的说法。

Virtual attribute 不存在相对应的同名实例变量,是对其他 attribute 操作而进行封装的实例方法。

示例,firstname,lastname 为属性,fullname 为虚拟属性:

class Person
  attr_accessor :firstname, :lastname

  def fullname
    "#{firstname} #{lastname}"
  end

  def fullname=(fullname)
    names = fullname.split
    self.firstname = naems[0]
    self.lastname = names[1]
  end
end

上面的代码其实等价于:

class Person
  def firstname
    @firstname
  end

  def firstname=(firstname)
    @firstname = firstname
  end

  def lastname
    @lastname
  end

  def lastname=(lastname)
    @lastname = lastname
  end

  def fullname
    "#{firstname} #{lastname}"
  end

  def fullname=(fullname)
    names = fullname.split
    self.firstname = naems[0]
    self.lastname = names[1]
  end
end

@nightire 的回答太赞了。

但是我看镐头书一直在说 attribute 可以看成一种方法,正如 @reyesyang 所说。

attr_accessor :firstname, :lastname 这段代码来说, :firstname. :lastnamesymbol, 也就是下面定义的方法, 对不对呢?

def lastname
   @lastname
end

def lastname=(lastname)
   @lastname
end

那我们,又说对象的 instance variable 也是它的attribute,所以我就比较迷茫了。

#6 楼 @springwq 嗯,应如 5 楼所述,说它是一种方法,其实指的是 getter/setter 方法。就好像你贴的代码那样,Ruby 类中定义的 attributes 实际上就是一对 getter/setter 方法。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册