2

Ruby の奇妙な点を見つけました。method_missing/を使用して、カーネルが同じメソッドを定義している場合、失敗しrespond_to_missing?て開始されたメソッド呼び出しを動的に処理します。__send__

class Testerize

  def method_missing(method, *args, &block)
    if method == :system
      puts 'yay'
    else
      super
    end
  end

  def respond_to_missing?(method, internal)
    return true if method == :system
  end

end

t = Testerize.new
puts t.respond_to?(:system)
# Prints true
t.system
# Prints 'yay'
t.__send__(:system)
# Exception: wrong number of arguments (ArgumentError)

Kernel.systemどういうわけか混ざり合っています。ここで何が起こっているか知っている人はいますか?:system「メッセージ」が Testerize インスタンスに投稿され、ヒットし、出来上がりを期待していたでしょうmethod_missing。直接呼び出しを使用しているときmethod_missingに使用すると呼び出されないのはなぜですか?__send__

関連する場合は、Ruby 1.9.3 を使用しています。

4

2 に答える 2

3
with '__send__' or 'send' we can even call private methods of the object.

スクリプトで次のようにします。

t.private_methods.grep /system/

systemメソッドが表示されますが、

t.methods.grep /system/

空の配列が表示されます。

__send__継承チェーンで Kernel から継承されたプライベート メソッドを呼び出そうとするため、代わりに__send__Ruby のpublic_sendメソッドを使用します。

于 2013-07-11T20:28:29.110 に答える
1

クラスの祖先チェーン ( Testerize.ancestors) を調べると、次のことがわかります。

[Testerize, Object, Kernel, BasicObject]

新しいクラスObjectはデフォルトで からObject継承され、 から継承されるKernelため、使用可能なインスタンス メソッドはすべてインスタンスで使用できKernelます。

于 2013-07-11T20:09:29.340 に答える