2016-09-12 17 views
3

這裏是隨機問題。我不確定這是否有一個術語,但是我想知道當你定義一個沒有明確接收方的方法時,你怎麼知道什麼類可以得到這個方法?是不是self就是在這種情況下?Ruby沒有明確的接收者時,什麼類可以獲得方法?

self在類定義的上下文中是被定義的類,並且用隱式接收器定義的方法被綁定到我們隨時可以看到的類。

但是,如果我限定實例方法中的一個方法,即「sub_method」是越來越放在外部類,以及:

[12] pry(main)> class A 
[12] pry(main)* def my_method 
[12] pry(main)*  puts self 
[12] pry(main)*  def sub_method 
[12] pry(main)*  puts self 
[12] pry(main)*  end 
[12] pry(main)* end 
[12] pry(main)* end 
=> :my_method 
[13] pry(main)> a = A.new 
=> #<A:0x007fa588181d40> 
[14] pry(main)> a.my_method 
#<A:0x007fa588181d40> 
=> :sub_method 
[15] pry(main)> a.sub_method 
#<A:0x007fa588181d40> 
=> nil 
[16] pry(main)> A.instance_methods(false) 
=> [:my_method, :sub_method] 

而且在頂層範圍,selfmain,這是在Object類的實例,但方法來定義有被添加到Object,不main小號單例類,這是我的基礎上如何我見過的其他特殊方法期待什麼工作:

這裏發生了什麼事,對此有規定,還是隻有這幾個案例才能知道?

回答

4

Ruby中有三個隱式上下文。

最着名的是self,當前對象和默認接收者。

第二個衆所周知的是用於恆定查找的範圍。一般來說,不斷的查詢是「詞彙外部,然後通過繼承向上」,但是有很多細微之處。 Ruby維護者稱這個上下文爲cref

你在問什麼,是the third context, sometimes called the default definee。通常,默認的定義是最近的詞彙封閉模塊。但是,您已經發現一個例外:在頂層,默認的定義實際上是Object(加上,默認的可見性private)。instance_eval同時改變self(到instance_eval消息的接收方)和默認definee(到接收方的單身類別)。 class_eval同時更改爲接收方。

+1

在你開始搜索它之前:那篇博客文章的作者提到的關於第三個隱式上下文的文章,從來沒有寫過,遺憾的是。 –

+1

對於那些不瞭解她的人:Yugui是Ruby 1.9的發佈經理,她負責我們熟悉的Ruby設計,開發,維護和發佈過程中的許多改進。有時會忘記Ruby 1.8的糟糕的舊日子。 –

6

我認爲你很容易混淆「接收者」,就像人們通常用術語來表示的那樣,「接收者」就像在「目標上下文中爲任何定義的方法」一樣。

在一個方法內調用def是允許的語法,但在風格方面非正統。 Ruby的這種做法是使用define_method,您可以更好地控制該方法的用途。把def想象成定義方法的簡單方法,但是上下文有點滑。如果在類上下文中調用它,則會定義一個實例方法。如果在實例方法中調用它,則會定義另一個實例方法。

更好的辦法是將該方法包裝在模塊中,稍後您可以使用includeextend

在頂級範圍定義方法main意味着您希望它們通用。最好的辦法是強制他們進入Object。這就是爲什麼在這種情況下定義方法可能會很匆忙,所以不推薦用於其他任何非常規的程序。

+0

是的我想我是指錯誤的接收器,我知道那裏的所有東西都是醜陋的,不應該做的;我想我試圖瞭解當沒有指定方法時,方法所屬的默認類是否與'self'是什麼有關,是它定義的地方。 – anthonygiuliano

+0

當進行方法調用時,上下文通常是可預測的,''self'在Ruby中不會改變,因爲'this'在JavaScript中執行。當使用'def'時,有幾個簡單的規則用於方法的去向,但它只是直接用於'main'或內部'class'或'module'。 – tadman

相關問題