当我在initialize方法中初始化实例变量时,使用@var = var_value
和self.send("var=", var_value)
之间有区别吗?我的意思是,有没有理由因为任何原因而偏爱另一种方式,即使这意味着风格的原因?
class MySuperClass
attr_accessor :columns, :options
end
class MySubClass < MySuperClass
def initialize(columns, options)
@columns = columns
@options = options
end
end
class MyOtherSubClass < MySuperClass
def initialize(columns, options)
self.send("columns=", columns)
self.send("options=", options)
end
end
答案 0 :(得分:4)
有区别。
@var = x
分配给实例变量。没有方法调用。没有虚拟调度。没有(明智的)方法来拦截任务。
send
调用方法(或“发送消息”)。在上下文中,:var=
是评估者“setter方法”,包装实例变量赋值。但它是一种方法,通过虚拟调度遵循继承来调用,并且可以做任何事情 - 包括在子类型中被覆盖。
@var = x
的真实等价物为instance_variable_set:
self.instance_variable_set(:@var, x)
在这种情况下使用send
是奇怪的。如果是意图,请直接使用访问者(self.columns = columns
)。
哪一个“更正确”取决于所建立的封装水平 - 以及在其类型和用途上定义的合同。当涉及子类型时,我通常在访问者一侧犯错。