[英]Ruby block, procs and instance_eval
我最近嘗試做類似這樣的事情:
a = "some string"
b = Proc.new{ upcase }
a.instance_eval b
這給出了錯誤:
類型錯誤:無法將 Proc 轉換為 String
但這有效:
def b(&block)
"some string".instance_eval &block
end
b{ upcase }
進一步看一下這個方法:
def b(&block)
"some string".instance_eval block
end
產生相同的Proc to String
錯誤。
所以......我對塊的理解是它們只是過程。 但顯然有這個&
符號有一些特別之處......
誰可以給我解釋一下這個? 是否可以將普通 proc 轉換為這個&block
對象的特殊之處?
剛剛想通了我的第二個問題,在 proc 前面加上&
......這很容易,但這到底在做什么?
要使第一個示例工作,您所要做的就是:
>> a.instance_eval &b #=> "SOME STRING"
原因是instance_eval
需要一個字符串或一個塊,而&符號提供后者。
不同之處在於a.instance_eval b
將b
作為常規參數傳遞給 instance_eval,而a.instance_eval &b
將其作為塊傳遞。 這是兩個不同的東西。
考慮這個方法調用:
obj.foo(bar) do |x|
stuff(x)
end
它使用一個常規參數 ( bar
) 和一個塊參數 ( do |x| stuff(x) end
) 調用方法foo
。 在方法定義中,它們通過在塊參數前加上&
來區分:
def foo(arg, &block)
如果你想傳遞一個變量表達式而不是一個文字塊,同樣可以通過在表達式前加上&來實現(它應該產生一個 Proc)。
如果你傳遞一個沒有&
的參數,它會進入arg插槽而不是塊插槽。 參數恰好是 Proc 的一個實例並不重要。 語法規定了方法如何傳遞和處理它。
這是因為 instance_eval 接受一個字符串來 eval 或一個塊。 instance_eval(&block)
正在將您的block
作為塊傳遞給 instance_eval。
關鍵的區別在於Proc 實例是一個對象,而塊不是一個對象。 &
是一個操作符,可以相互交換塊和 Proc 實例。
方法的所有參數都必須是對象。 除了參數之外,方法還可以接受一個塊。 instance_eval
是一種接受字符串參數或塊的方法。 傳遞 Proc 對象不會滿足這兩種情況。 如果將&
附加到 Proc 對象,它將作為塊處理。
這將起作用:
a = "some string"
b = Proc.new{ upcase }
a.instance_eval &b
instance_eval
方法可以接收塊參數。 b
是一個Proc
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.