@var = var_val和self.send(“var =”,var_val)之间有区别吗?

时间:2016-05-28 20:59:35

标签: ruby

当我在initialize方法中初始化实例变量时,使用@var = var_valueself.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

1 个答案:

答案 0 :(得分:4)

有区别。

@var = x分配给实例变量。没有方法调用。没有虚拟调度。没有(明智的)方法来拦截任务。

send 调用方法(或“发送消息”)。在上下文中,:var=是评估者“setter方法”,包装实例变量赋值。但它是一种方法,通过虚拟调度遵循继承来调用,并且可以做任何事情 - 包括在子类型中被覆盖。

@var = x的真实等价物为instance_variable_set

self.instance_variable_set(:@var, x)

在这种情况下使用send是奇怪的。如果是意图,请直接使用访问者(self.columns = columns)。

哪一个“更正确”取决于所建立的封装水平 - 以及在其类型和用途上定义的合同。当涉及子类型时,我通常在访问者一侧犯错。