实例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
方法中使用@age
和self.age
之间的区别。
写入@age
直接访问实例variables@age
。 写self.age
告诉对象自己发送消息的age
,通常会返回实例variables@age
– 但可以做任何其他的事情,取决于在给定的子类如何实现age
方法。 例如,你可能有一个MiddleAgedSocialite类,总是报告比其实际年龄小10岁的年龄。 或者更实际上,PersistentPerson类可能懒惰地从持久存储中读取数据,将其所有持久数据caching在散列中。
不同之处在于,它将执行方法的使用隔离开来。 如果财产的执行发生变化 – 比如说保留出生date,然后根据现在和出生date之间的时间差来计算年龄 – 那么取决于方法的代码就不需要改变。 如果直接使用该属性,则需要将该更改传播到代码的其他区域。 从这个意义上说,直接使用属性比使用类提供的接口更脆弱。
当你从Struct.new
inheritance一个类时,会被警告,这是一个生成初始化器的简单方法( 如何在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.age
和other_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 – 指实例属性的年龄。