Ruby类:初始化self vs. @variable

时间:2012-08-23 18:15:19

标签: ruby

有人可以解释在定义类时初始化“self”和@variables之间的区别吗?

这是一个例子

class Child < Parent
  def initialize(self, stuff):
    self.stuff = stuff
    super()
  end
end

所以在这种情况下,我无法用self.stuff替换@stuff吗?有什么不同?另外,super()只是意味着Parent初始化方法中的Child应该只是继承它吗?

2 个答案:

答案 0 :(得分:38)

一般来说,不,self.stuff = stuff@stuff = stuff是不同的。前者对对象进行stuff=方法调用,而后者直接设置实例变量。前者调用一个可能是公共的方法(除非在类中特别声明为private),而后者总是设置一个私有实例变量。

通常,它们看起来一样,因为在类上定义attr_accessor :stuff是很常见的。 attr_accessor大致相当于以下内容:

def stuff
  @stuff
end

def stuff=(s)
  @stuff = s
end

因此,在这种情况下,它们在功能上是相同的。但是,可以定义公共接口以允许不同的结果和副作用,这将使这两个“作业”明显不同:

def stuff
  @stuff_called += 1    # Keeps track of how often this is called, a side effect
  return @stuff
end

def stuff=(s)
  if s.nil?             # Validation, or other side effect. This is not triggered when setting the instance variable directly
    raise "Argument should not be nil"
  end
  @stuff = s
end

答案 1 :(得分:6)

除非您专门创建self.stuff=来修改该值,否则实际上无法使用attr_writer

事实上,这些是等价的:

class Child
  attr_writer :stuff
end

class Child
  def stuff=(val)
    @stuff = val
  end
end

如果这是您想要的功能,而不是显式方法,则更常见的是使用attr_writer。但是,如果要执行额外的错误检查或更改分配的工作方式,通常会使用显式方法。

关于何时使用@stuff =以及何时使用self.stuff =的问题,如果您只有简单的作业,并且您的课程很简单,我会使用前者,如果您的课程很简单,我会使用前者您的要求可能会变得更加复杂。还有很多其他原因,但它更多的是风格而不是其他任何原因。