正如我return在 a 中理解的那樣Proc終止當前方法。所以在下面的例子中,我希望看到:a1 > b1 > proc > a2。但實際上它從未達到a2,為什么呢?
def a
puts "a1"
l = Proc.new {puts "proc"; return}
b l
puts "a2"
end
def b x
puts "b1"
x.call
puts "b2"
end
a
uj5u.com熱心網友回復:
作為一般規則,return總是從最接近的詞法封閉方法定義運算式回傳。
在這種情況下,最接近的詞法封閉方法定義運算式是def a,因此,return從 回傳a。
return在這種情況下,在塊內實際上并不重要。通用規則是通用的,因此無論出現在哪里,它都適用return。
但是,如果我們更具體地看一下塊,我們會發現它仍然有意義:在塊中,區域變數在詞法上被捕獲,self在詞法上被捕獲,因此它在return詞法上的行為也是有意義的。塊的一個普遍特性是,如果你想了解一個塊中發生了什么,你只需要在詞匯上向外看。
如果我們更具體,首先從一般規則到塊,現在從塊到Procs,行為仍然有意義:aProc本質上是一個具體化的塊,所以 aProc表現得像塊是有道理的。
這里有一些例外,不過,在一般情況下,和其中重要的一條是lambda運算式。在 Ruby 中談論 lambda 總是有點奇怪,因為 lambda 是Procs,但它們的行為與Procs不同。IMO,lambdas 應該在Procs旁邊有一個單獨的類。由于 lambdas 是Procs,所以談論 lambdas 和Procs之間的差異變得很奇怪,因為它們不是 lambdas(它們沒有標準化的名稱,因此也被混淆地稱為Procs)。
lambda 的行為Proc在兩個方面不同于非 lambda 的行為,其中之一與您的問題相關:
- 非 lambda
Procs 中的引數系結與塊中的引數系結具有相同的語意,而 lambda 中的引數系結與訊息發送/方法呼叫中的引數系結具有相同的語意。 - 在非 lambda
Procs 中,return從最接近的詞法封閉方法定義運算式回傳,就像在塊中一樣,而在 lambdas 中,return從 lambda 本身回傳,就像return在方法中一樣。
因此,在這兩個方面,非 lambdaProc的行為類似于塊,而 lambda 的行為類似于方法。我像這樣記住它:“ Proc”與“block”押韻,“lambda”和“method”都是希臘語。
您可能知道,有些方法也會改變傳遞給它們的塊的行為。例如instance_eval,instance_exec改變 的值self,define_method實際上確實改變了 的行為return。
但是由于您一般沒有詢問塊,也沒有專門詢問 lambda,并且您的問題中沒有反射方法,因此一般規則仍然適用于非 lambda Procs,如您的問題中所示:return從最接近的詞法封閉方法定義運算式回傳。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/362102.html
上一篇:Puma初始化后不會繼續監聽
