sar*_*unw 175 ruby instance-variables self
这是一些代码:
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
Run Code Online (Sandbox Code Playgroud)
我想知道的是两者的区别@age
,并self.age
在age_difference_with
方法.
Chu*_*uck 255
写入@age
直接访问实例变量@age
.编写self.age
告诉对象向自己发送消息age
,消息通常会返回实例变量@age
- 但可以执行任何其他操作,具体取决于age
方法在给定子类中的实现方式.例如,您可能有一个MiddleAgedSocialite类,它总是报告其年龄比实际年龄小10岁.或者更实际上,PersistentPerson类可能会懒惰地从持久性存储中读取该数据,并将所有持久性数据缓存在散列中.
tva*_*son 23
不同之处在于它正在将该方法的使用与其实现隔离开来.如果财产的实施要改变 - 比如保持生日,然后根据现在和生日之间的时间差计算年龄 - 那么取决于方法的代码不需要改变.如果它直接使用该属性,那么更改将需要传播到代码的其他区域.从这个意义上讲,直接使用属性比使用类提供的接口更脆弱.
当你继承一个Struct.new
生成初始化器的简洁方法的类时,请注意(如何在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()
Run Code Online (Sandbox Code Playgroud)
将返回
30
nil
Run Code Online (Sandbox Code Playgroud)
但是,当您删除初始化程序时,它将返回
nil
30
Run Code Online (Sandbox Code Playgroud)
随着类的定义
class Node2
attr_accessor :value
def initialize(value)
@value = value
end
def show()
p @value
p self.value
end
end
Run Code Online (Sandbox Code Playgroud)
你应该提供构造函数.
n2 = Node2.new(30)
n2.show()
Run Code Online (Sandbox Code Playgroud)
将返回
30
30
Run Code Online (Sandbox Code Playgroud)
第一个答案是完全正确的,但作为一个相对的新手,我并没有立即清楚它的含义(向自己发送消息?嗯……)。我认为一个简短的例子会有所帮助:
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
Run Code Online (Sandbox Code Playgroud)