5

私はRubyでリフレクティブメソッドを使用しようとしていますが、本当に驚いた動作に遭遇しました。

次の例は、IRBとルビースクリプトと呼ばれる場合で動作が異なるようです。

例1:

def myfun; end
p respond_to?(:myfun)

IRbでは、これは「true」、スクリプトでは「false」と言います。

例2:

ml = methods
def myfun; end
p methods - ml

IRbでは、これは[:myfun]と言います。スクリプト内:[]。

これは1.8、1.9 MRI、JRuby 1.5.6などで見つかりました。したがって、これは正常であると思います。

なぜ違いがあるのですか?

私はかなり確信していました'respond_to?' メソッドが利用可能かどうかを確認する方法はあります-上記の場合にそれが機能しないのはなぜですか?

4

1 に答える 1

5

この関数(「メイン」オブジェクトのメソッド)は、rubyスクリプトでプライベートとして定義されています。これは簡単に確認できます。

ml = private_methods
def myfun; end
p private_methods - ml #=> [:myfun]
p respond_to?(:myfun, true) #=> true

自分で明示的に呼び出すと、エラーが発生します。

self.myfun
# NoMethodError: private method ‘myfun’ called for main:Object

一方、IRBでは、メソッドはパブリックとして定義されています。ボンネットの下では、次のようになります。

class Object
  def irb_binding
    # this is where your entered code is evaluated
    def myfun; :ok; end # you can define methods in other methods
    self.myfun # and they are public by default
  end
end

p irb_binding # :ok

IRBはトップレベルで簡単に評価できますが、代わりに、ローカル変数が共有されないように、メソッドを使用して別の環境を作成します。

require "irb"
foo = :ok
IRB.start
#>> foo
# NameError: undefined local variable or method `foo' for main:Object

メソッドが公開されているのは、実装による偶然の一致であり、それほど重要ではないと思います。これらのメソッドはとにかく一時的なものです。

于 2013-03-04T16:56:49.060 に答える