Ruby getter真的不修改实例变量吗?
我在电视上看到这个: 使用getter,可以获得@a的当前值,而无需修改它 使用setter,可以修改@a,并将其新值作为返回值 然而,从中查看这段代码,我发现setter和getter实际上都在对其中的变量做一些事情Ruby getter真的不修改实例变量吗?,ruby,getter-setter,Ruby,Getter Setter,我在电视上看到这个: 使用getter,可以获得@a的当前值,而无需修改它 使用setter,可以修改@a,并将其新值作为返回值 然而,从中查看这段代码,我发现setter和getter实际上都在对其中的变量做一些事情 def roles=(roles) self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) end def roles ROLES.reject do |r|
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
def roles
ROLES.reject do |r|
((roles_mask || 0) & 2**ROLES.index(r)).zero?
end
end
看起来getter实际上返回了一个真值,如果不是真值,至少是某种转换。那么,这条“getter无需修改即可获取,setters设置需修改”规则是否真的成立?这是错误的看待“getter”和“setters”的方式。相反,你可以这样想: setter更改对象的状态。它可能设置一个简单的实例变量。它可能会设置多个实例变量。在发布的代码中,它可能会在保存信息之前转换信息 getter检索有关对象状态的一些信息。不管这是什么;它可以是直接存储在实例变量中的值。也可以是基于对象当前状态的其他值,如post中的值 通常建议getter和setter获取/返回相同类型的值,并以一致的方式影响/报告对象状态。在上面的示例中,公开类型是一个“角色数组”,它表示与对象关联的角色
使用额外命名的方法可以更清楚地显示发布代码的意图,因为可以提取出复杂的建筑/消费表达式;注意对称性:
def toMaskFromArray (roles)
(roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+)
end
def toArrayFromMask (mask)
ROLES.reject do |r|
((mask || 0) & 2**ROLES.index(r)).zero?
end
end
def roles=(roles)
self.roles_mask = toMaskFromArray(roles)
end
def roles
toArrayFromMask(self.roles_mask)
end
那么它就不必返回实例变量了?第二个方法返回的是真值,对吗?它不一定是“简单”的实例变量表达式(例如
@a
)。getter/setter实际上将一系列角色编码/解码为一个内部整数(其中每个角色由一个特定的“位”表示);这样就避免了必须在阵列周围。getter返回一个数组,因为它将整数“分解”回相应的序列。