簡體   English   中英

紅寶石頂層定義的方法在哪里?

[英]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.metamain本征類):

self.meta.private_instance_methods(false).include?(:hello) #=> true

似乎hello方法同時在main和Object本征類上定義。 這是怎么回事? 請注意, private_instance_methodsfalse參數從方法列表中排除超類方法。

首先,這種行為和潛在的推理一直存在; 這對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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM