about 10 years ago
Proc 與 yield 的差別在於,proc 會將 block 給暫存起來,等到需要用的時候,再以 block.call 的方式呼叫出來,yield 則是自動執行 block.call 。
新增一個 proc object 的做法有兩種,proc & lambda。
#Proc New
my_proc = Proc.new { puts "tweet" }
my_proc.call
#Lambda
my_proc = lambda { puts "tweet" } #1.9以上版本也可以寫成 my_proc = -> { puts "tweet" }
my_proc.call
#result
"twitter"
Proc 也可讓你執行兩個以上的 block
class Tweet
def post(success, error)
if current_user
success.call
else
error.call
end
end
end
tweet = Tweet.new
success = lambda { puts "Sent!"}
error = lambda { puts "No user login"}
tweet.post(success, error)
Proc 如果要轉換成 block
tweets = ["First tweet", "Second tweet"]
printer = lambda { |tweet| puts tweet }
tweets.each(printer) # 會噴錯誤,因為each吃的是block
tweets.each(&printer) # 加上 '&' 就可將proc轉換成block
而 proc 和 lambda 到底有哪些差異的地方?
Lambdas 會檢查傳入的參數,而Procs不會
def puts_parameters(code)
code.call(1, 2)
end
l = lambda { |a, b, c| puts "#{a} is a #{a.class}, #{b} is a #{b.class}, #{c} is a #{c.class}" }
p = Proc.new { |a, b, c| puts "#{a} is a #{a.class}, #{b} is a #{b.class}, #{c} is a #{c.class}" }
puts_parameters(l)
#result
"ArgumentError: wrong number of arguments (2 for 3)"
puts_parameters℗
#result
"1 is a Fixnum, 2 is a Fixnum, is a NilClass"
Lambdas 會直接skip return,而 Procs不會
def return_using_proc
Proc.new { return "Hi from proc!"}.call
puts "end of proc call"
end
def return_using_lambda
lambda {return "Hi from lambda!"}.call
puts "end of lambda call"
end
return_using_proc
#result
"Hi from proc!"
return_using_lambda
#result
"end of lambda call"