2013-03-04 40 views
5

我試圖在Ruby中使用反射方法,並運行成我覺得非常驚訝的行爲。爲什麼Module.methods()和respond_to?在irb中的作用與在腳本中的作用不同?

下面的例子似乎在IRB的工作方式不同,並呼籲Ruby腳本時:

例1:

def myfun; end 
p respond_to?(:myfun) 

在IRB,該說 '真', 腳本: '假' 。

實施例2:

ml = methods 
def myfun; end 
p methods - ml 

在IRB,這表示[:myfun]。 在腳本中:[]。

我發現1.8,1.9 MRI,JRuby 1.5.6等等 - 所以我認爲這是正常的。爲什麼不同?

我很確定'respond_to?'是方法來看看方法是否可用 - 爲什麼在上述情況下不起作用?

回答

5

此函數 - 「main」對象上的方法 - 在ruby腳本中定義爲private。 您可以輕鬆地檢查:

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 

我認爲公開的方法由於實施而只是巧合,並不重要。無論如何這些方法都是臨時的。

+0

很好的知道 - 這是驚人的我經歷了多年的Ruby暴露後沒有遇到這個問題..是的,我對IRB爲什麼要公開它試圖變得更友好 - 是嗎? :)我可以明白爲什麼他們通常是私人的 - 爲了避免混淆像「def f; end; class A; end; A.new.f」,或類似的東西? – inger 2013-03-04 17:08:22

+0

我也很驚訝地瞭解到這一點。 – 2013-03-04 17:16:23

+0

@Semyon你能解釋爲什麼'irb'方法是公開的嗎?爲什麼在'irb'' myfun'和'self.myfun'指的是同樣的方法? – codeit 2013-03-04 17:17:15

相關問題