Proc對象
Proc是由塊轉換來的對象。建立一個Proc共有四種方法,分別是:
範例程式碼
# 法一inc = Proc.new { | x | x + 1}inc.call(2) #=> 3# 法二inc = lambda {| x | x + 1 }inc.call(2) #=> 3# 法三inc = ->(x) { x + 1}inc.call(2) #=> 3# 法四inc = proc {|x| x + 1 }inc.call(2) #=> 3
除了上面的四種之外,還有一種通過&操作符的方式,將代碼塊與Proc對象進行轉換。如果需要將某個代碼塊作為參數傳遞給方法,需要通過為這個參數添加&符號,並且其位置必須是在參數的最後一個
&符號的含義是: 這是一個Proc對象,我想把它當成代碼塊來使用。去掉&符號,將能再次得到一個Proc對象。
範例程式碼
def my_method(&the_proc) the_procendp = my_method {|name| “Hello, #{name} !”}p.class #=> Procp.call(“Bill”) #=> “Hello,Bill”def my_method(greeting) “#{greeting}, #{yield}!”endmy_proc = proc { “Bill” }my_method(“Hello”, &my_proc)
一些需要注意的地方
在使用block時,我會忽略proc的存在,我將proc定位為一個幕後的工作者。我經常寫類似下面的代碼,
def f(...) ... yield ... end def f(..., &p) ... p.call ... end def f(..., &p) instance_eval &p ... end def f(..., &p) ... defime_method m, &p ... end
有些新手會寫類似下面的一執行就會報錯的代碼,
def f(..., &p) instance_eval p end def f(..., p) instance_eval p.call end
也有這樣寫的,
def f(..., &p) instance_eval do p.call end end
或者
def f(...) instance_eval do yield end end
我甚至寫過類似下面的代碼,
def f(...) instance_eval yield end
我們經常在該掛block的時候,卻把proc對象當參數傳給方法了, 或者不明白&p就是block可以直接交給方法使用,我曾經也犯過這樣的錯誤就是因為沒有把block和proc正確的區分開來, &p是block, p是proc,不到萬不得已的情況下不要顯式地建立proc,每當我對block和proc之間的關係犯糊塗時,我就會念上幾句。