2013-03-04 5 views
5

私はRubyでリフレクションメソッドを使用しようとしていて、本当に魅力的な振る舞いをしています。なぜModule.methods()とrespond_toですか?スクリプトとは違ってirbで動作しますか?

次の例では、IRBに異なる動作をするようだと、Rubyスクリプトと呼ばれるとき:

例1:IRBでは

def myfun; end 
p respond_to?(:myfun) 

、これは '真' と言い、スクリプトで : '偽の' 。

例2:IRBで

ml = methods 
def myfun; end 
p methods - ml 

、これは言う[:myfunはつぎ]。 スクリプト中:[]。

私はこれを1.8,1.9 MRI、JRuby 1.5.6などで見つけました。これは正常だと思います。

なぜ違いがありますか?

私はかなり 'respond_to'でしたか?メソッドが利用可能かどうかを確認する方法です - なぜ上のケースでは機能しないのですか?

答えて

5

"main"オブジェクトに関するこの関数のメソッドは、ルビスクリプトではprivateとして定義されています。 あなたは簡単にこれをチェックすることができます:あなたは自分で明示的に呼び出した場合

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

は、あなたがエラーを取得する:あなたのメソッドはpublicとして定義されてIRBに一方

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

を、。

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 

を私はボンネットの下には、次のようになりますメソッドが公開されていると思うのは、実装に起因する単なる偶然であり、それほど重要ではありません。これらの方法はとにかく一時的です。

+0

Rubyの長年の暴露後に私はこれに遭遇していないことは驚くべきことです。はい、私はIRBが一般に公開している理由に興味があります。 :)私はなぜ彼らがプライベートであるのかを見ることができます - "def f; end; class A; end; A.new.f"などのような混乱を避けるためですか? – inger

+0

私もこれを知って驚いた。 –

+0

@セミオンなぜ 'irb'メソッドが公開されているのか説明できますか?そしてなぜ「irb」の中で「myfun」と「self.myfun」が同じ方法を指しているのでしょうか? – codeit

関連する問題