10

最近、キーワードが現在のコンテキストで使用できるdefined?かどうかをチェックするために使用される演算子で、いくつかの奇妙な動作に遭遇しました。通常は問題なく動作しますが、チェックと少しのメタプログラミングsuperを組み合わせようとすると、予期しない結果が得られました。defined? super

説明するよりも表示する方が簡単なので、問題を説明するための抜粋した例を次に示します。

class A; 
  def self.def_f!; 
    singleton_class.send(:define_method, :f) { defined? super }
  end
end
class AA < A; end

AおよびAAクラスには両方とも.def_f!クラスメソッドがあります)

A.def_f!

A.f  # => nil
AA.f # => nil

A.fスーパーがなく、にAA.fディスパッチするA.fので、これまでのところすべて問題ありませんが...)

AA.def_f! # define its own .f method in the AA class

AA.f # => "super"
A.f  # => "super" # WHY???

誰かが私に最後の行を説明できますか?A.fスーパーメソッドがないのに、なぜ"super"代わりに戻るのnilですか?バグですか?

(1.9.2と1.9.3で試しました。同じ結果です)

UPD: Rubyバグトラッカーでチケットを開きました:http://bugs.ruby-lang.org/issues/6644

4

2 に答える 2

2

わかりました、@Niklas は正しかったので、この問題を Ruby バグトラッカーに報告し、バグを確認して修正しました: https://bugs.ruby-lang.org/issues/6644

私の知る限り、この修正は ruby​​ 2.0.0 に含まれる予定です。

于 2012-07-14T12:17:02.920 に答える
1

ええ、いくつかの癖がありますが、これは実際にdefine_methodは問題ではありませんが、 . そうは言っても、このようなエッジケースに遭遇するたびに、通常はRubyコードの文字列を評価するだけで、常に期待どおりに動作します.defined?(super)define_methoddefine_method

module M;
  def def_f!
    singleton_class.class_eval <<-RUBY
      def f
        defined?(super)
      end
    RUBY
  end
end

class A; extend M; end
class AA < A; end

A.def_f!

p A.f  # => nil
p AA.f # => nil

AA.def_f! # define its own .f method in the AA class

p AA.f # => "super"
p A.f # => nil

なぜこのように動作するのかについては、私は Ruby のソースについて十分な経験がありません。おそらく、私よりも多くのことを知っている人が協力してくれるでしょう。しかし、実用的な目的では、文字列を評価することは常に私にとってうまくいきました。

于 2012-06-24T22:25:31.030 に答える