2

「スーパー」を呼び出すことができる場合とできない場合を理解するのに少し苦労しています。以下の例では、スーパーメソッドはスーパークラスエラーなしになります。

class Bacterium
  def eats
    puts "Nam"
  end
end

class Bacterium
  def eats
    super # -> no superclass error
    puts "Yam"
  end
end

b = Bacterium.new
b.eats

しかし、これは機能します:

class Fixnum
  def times
    super # -> works
    puts "done"
  end
end

5.times { |i| puts i.to_s }

5はFixnumのインスタンスだけではありません。そして、私は上記のバクテリアの例のように既存の方法を再定義していませんか?

4

2 に答える 2

4

いいえ、そうではありません。Fixnumクラスから継承しInteger、実際にはオーバーライドしているので、親から実装を呼び出すInteger#timesので機能します。super

モンキーパッチを適用するときに同様のことを実現するには、メソッドを再定義する前にエイリアスを作成し、エイリアスで呼び出す必要があります。

class Bacterium
  alias_method :eats_original, :eats
  def eats
    eats_original # -> "Nam"
    puts "Yam"
  end
end

クラスの再開は継承の一形態ではなく、superそこでは役に立ちません。

于 2010-12-13T07:23:49.837 に答える
3

Mladenが言ったように、あなたはそれを次のようにチェックすることができますClass#superclass

irb> Fixnum.superclass
=> Integer

そして、Integerは実装し#timesますか?:

irb> Integer.instance_methods.grep /times/
=> [:times]

はい、そうです。

したがって、簡単に言えば、superはスーパークラスのメソッドを呼び出すと言えます。あなたの場合、aのスーパークラスBacteriumはObjectであり、これはを実装していません#eats

この例を見ると、これは非常に単純化されていると言いました。

module One
  def hi
    " World" << super()
  end
end

module Two
  def hi
    "Hello" << super()
  end
end

class SayHi
  def hi
    "!!!"
  end
end

h = SayHi.new
h.extend(One)
h.extend(Two)

puts h.hi

#=> Hello World!!

私がここに書いたことを真剣に受け止めないでください。これは実際にはRubyオブジェクトモデルの氷山の一角であり、理解することが重要です(私はまだそれを学んでいます)。そうすれば、これらの概念のほとんどまたはすべてを理解できます。

「Rubyオブジェクトモデル」にはGo​​ogle-fuを使用してください...

于 2010-12-13T09:30:30.587 に答える