实例variables:self vs @

这里是一些代码:

class Person def initialize(age) @age = age end def age @age end def age_difference_with(other_person) (self.age - other_person.age).abs end protected :age end 

我想知道的是在age_difference_with方法中使用@ageself.age之间的区别。

写入@age直接访问实例variables@age 。 写self.age告诉对象自己发送消息的age ,通常会返回实例variables@age – 但可以做任何其他的事情,取决于在给定的子类如何实现age方法。 例如,你可能有一个MiddleAgedSocialite类,总是报告比其实际年龄小10岁的年龄。 或者更实际上,PersistentPerson类可能懒惰地从持久存储中读取数据,将其所有持久数据caching在散列中。

不同之处在于,它将执行方法的使用隔离开来。 如果财产的执行发生变化 – 比如说保留出生date,然后根据现在和出生date之间的时间差来计算年龄 – 那么取决于方法的代码就不需要改变。 如果直接使用该属性,则需要将该更改传播到代码的其他区域。 从这个意义上说,直接使用属性比使用类提供的接口更脆弱。

当你从Struct.newinheritance一个类时,会被警告,这是一个生成初始化器的简单方法( 如何在Ruby中生成初始化器? )

 class Node < Struct.new(:value) def initialize(value) @value = value end def show() p @value p self.value # or `p value` end end n = Node.new(30) n.show() 

将返回

 30 nil 

但是,当您删除初始化程序时,它将返回

 nil 30 

用类的定义

 class Node2 attr_accessor :value def initialize(value) @value = value end def show() p @value p self.value end end 

你应该提供构造函数。

 n2 = Node2.new(30) n2.show() 

将返回

 30 30 

没有任何区别。 我怀疑这是为了看到other_person.age靠近self.ageother_person.age的文件价值。

我想这种使用确实允许将来写入一个实际的getter,这可能会做一些比只返回一个实例variables更复杂的东西,在这种情况下,这个方法不需要改变。

但是,这不太可能是抽象的,毕竟,如果对象的实现改变了改变其他方法的合理性,那么在对象本身内的简单引用是完全合理的。

在任何情况下,抽象的age属性仍然不能解释明确使用self ,因为只是普通的age也会引用访问者。

第一个答案是完全正确的,但是作为一个相对的新手,我并不清楚它的含义(发送消息给自己,呃呃…)。 我认为一个简短的例子将有助于:

 class CrazyAccessors def bar=(val) @bar = val - 20 # sets @bar to (input - 20) end def bar @bar end def baz=(value) self.bar = value # goes through `bar=` method, so @bar = (50 - 20) end def quux=(value) @bar = value # sets @bar directly to 50 end end obj = CrazyAccessors.new obj.baz = 50 obj.bar # => 30 obj.quux = 50 obj.bar # => 50 

@age – 绝对是实例variables的年龄

self.age – 指实例属性的年龄。