14

クラスを定義するときに「自己」を初期化することと@変数を使用することの違いを誰かが説明できますか?

これが例です

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

self.stuffこの場合、 に置き換えることはできません@stuffか? 違いは何ですか?また、super()親の初期化メソッドにあるものは何でも、子はそれを正しく継承する必要がありますか?

4

2 に答える 2

37

一般的に、いいえ、self.stuff = stuff@stuff = stuffは異なります。前者はオブジェクトに対してメソッド呼び出しをstuff=行いますが、後者はインスタンス変数を直接設定します。前者は(クラスで特にプライベートとして宣言されていない限り)パブリックである可能性のあるメソッドを呼び出しますが、後者は常にプライベートインスタンス変数を設定します。

通常、attr_accessor :stuffクラスで定義するのが一般的であるため、同じように見えます。attr_accessorほぼ次と同等です。

def stuff
  @stuff
end

def stuff=(s)
  @stuff = s
end

したがって、その場合、それらは機能的に同一です。ただし、パブリックインターフェイスを定義して、異なる結果と副作用を許容することは可能です。これにより、これら2つの「割り当て」が明らかに異なります。

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
于 2012-08-23T18:26:12.977 に答える
6

その値を変更するためself.stuff=の を具体的に作成しない限り、実際には使用できません。attr_writer

実際、これらは同等です。

class Child
  attr_writer :stuff
end

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

attr_writer明示的な方法ではなく、必要な機能である ifを使用する方が一般的です。ただし、追加のエラー チェックを実行したり、割り当ての動作方法を変更したりする場合は、明示的な方法を使用することがよくあります。

@stuff =いつ使用するか、いつ使用するかという質問に対して、self.stuff =単純な割り当てしかなく、クラスが単純な場合は前者を使用し、要件がより複雑になる可能性がある場合は後者に移行します。他にも多くの理由がありますが、何よりもスタイルの問題です。

于 2012-08-23T18:23:18.290 に答える