簡體   English   中英

Ruby 塊、procs 和 instance_eval

[英]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 bb作為常規參數傳遞給 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.

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