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_proc
end
p = my_method {|name| “Hello, #{name} !”}
p.class #=> Proc
p.call(“Bill”) #=> “Hello,Bill”
def my_method(greeting)
“#{greeting}, #{yield}!”
end
my_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之間的關系犯糊涂時,我就會念上幾句。
您可能感興趣的文章:- 深入理解Ruby中的代碼塊block特性
- Ruby中的block代碼塊學習教程
- 詳解Ruby中的代碼塊及其參數傳遞