[英]Where are methods defined at the ruby top level?
在頂層,方法定義應該導致Object
上的私有方法,並且測試似乎證實了這一點:
def hello; "hello world"; end
Object.private_instance_methods.include?(:hello) #=> true
Object.new.send(:hello) #=> "hello world"
但是,以下也適用於頂層( self.meta
是main
本征類):
self.meta.private_instance_methods(false).include?(:hello) #=> true
似乎hello
方法同時在main和Object
本征類上定義。 這是怎么回事? 請注意, private_instance_methods
的false
參數從方法列表中排除超類方法。
首先,這種行為和潛在的推理一直存在; 這對1.9來說並不新鮮。 它發生的技術原因是因為main
是特殊的,並且處理方式與任何其他對象不同。 沒有花哨的解釋:它的行為方式是因為它是這樣設計的。
好的,但為什么呢? main
神奇的原因是什么? 因為Ruby的設計師Yukihiro Matsumoto認為它使語言更好地具有這種行為:
是這樣,為什么頂級方法不在這個對象上制作單例方法,而不是作為Object類本身的實例方法(因此被引入所有其他類,即比通常預期更多的命名空間污染)。 這仍然允許頂級方法調用其他頂級方法。 如果頂級對象被像Main這樣的常量引用,則可以使用Main.method(...)從任何地方調用這些方法。
你真的希望到處輸入“Main.print”嗎?
在討論中,他解釋說它表現得這樣,因為他覺得“假設是自然的”。
在回答您的評論時,您的問題是針對為什么main的本征類似乎將hello
作為私有實例方法報告。 問題在於,沒有任何頂級函數實際添加到main
,而是直接添加到Object
。 當使用本征類時, instance_methods
函數族總是表現得好像本征類仍然是原始類。 也就是說,類中定義的方法被視為直接在本征類中定義。 例如:
class Object
private
def foo
"foo"
end
end
self.send :foo # => "foo"
Object.private_instance_methods(false).include? :foo # => true
self.meta.private_instance_methods(false).include? :foo # => true
class Bar
private
def bar
"bar"
end
end
bar = Bar.new
bar.send :bar # => "bar"
Bar.private_instance_methods(false).include? :bar # => true
bar.meta.private_instance_methods(false).include? :bar # => true
但是我們可以直接在main
的本征類中添加一個方法。 將您的原始示例與此進行比較:
def self.hello; "hello world"; end
Object.instance_methods.include? :hello # => false
self.meta.instance_methods.include? :hello # => true
好的,但是如果我們真的想知道給定函數是在本征類上定義的,而不是原始類呢?
def foo; "foo"; end #Remember, this defines it in Object, not on main
def self.bar; "bar"; end #This is defined on main, not Object
foo # => "foo"
bar # => "bar"
self.singleton_methods.include? :foo # => false
self.singleton_methods.include? :bar # => true
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.