1. 主要区别:
参数列表中最多只能有一个 Block,但是可以有多个 Proc 或 Lambda
Lambda 对参数的检查很严格,而 Proc 则比较宽松
Proc 和 Lambda 中 return 关键字的行为是不同的
2. 特殊符号
The '&' tells ruby to turn the proc into a block
Sale.limit(5).map(&:id)
:id
是一个 symbol 对象,当在其前面加上&
就表示后边需要的是一个 proc,因此:id
会调用其 to_sym 方法。
3. 具体代码分析
# Block Examples
[1,2,3].each { |x| puts x*2 } # block is in between the curly braces
[1,2,3].each do |x|
puts x*2 # block is everything between the do and end
end
# Proc Examples
p = Proc.new { |x| puts x*2 }
[1,2,3].each(&p) # The '&' tells ruby to turn the proc into a block
proc = Proc.new { puts "Hello World" }
proc.call # The body of the Proc object gets executed when called
# Lambda Examples
lam = lambda { |x| puts x*2 }
[1,2,3].each(&lam)
lam = lambda { puts "Hello World" }
lam.call
p = Proc.new { puts "Hello World" }
p.call # prints 'Hello World'
p.class # returns 'Proc'
a = p # a now equals p, a Proc instance
p # returns a proc object '#<Proc:0x007f96b1a60eb0@(irb):46>'
{ puts "Hello World"} # syntax error
a = { puts "Hello World"} # syntax error
[1,2,3].each {|x| puts x*2} #
p 是类 Proc 的一个实例对象,其可以调用方法,复制给其他变量,也可以返回自己. block 是方法调用的一部分,不可以单独存在,
def multiple_procs(proc1, proc2,&block)
proc1.call
proc2.call
block.call
end
a = Proc.new { puts "First proc" }
b = Proc.new { puts "Second proc" }
multiple_procs(a,b) {puts "block"}
proc = Proc.new { puts "Hello world" }
lam = lambda { puts "Hello World" }
proc.class # returns 'Proc'
lam.class # returns 'Proc'
proc # returns '#<Proc:0x007f96b1032d30@(irb):75>'
lam # returns '<Proc:0x007f96b1b41938@(irb):76 (lambda)>'
proc 和 lam 都是 Proc 的实例对象,仅有微小的不同 参数检查的不同
proc = Proc.new { |x| puts x } # creates a proc that takes 1 argument
proc.call(2) # prints out 2
proc.call # returns nil
proc.call(1,2,3) # prints out 1 and forgets about the extra arguments
lam = lambda { |x| puts x } # creates a lambda that takes 1 argument
lam.call(2) # prints out 2
lam.call # ArgumentError: wrong number of arguments (0 for 1)
lam.call(1,2,3) # ArgumentError: wrong number of arguments (3 for 1)
def lambda_test
lam = lambda { return }
lam.call
puts "Hello world"
end
lambda_test # calling lambda_test prints 'Hello World'
def proc_test
proc = Proc.new { return }
proc.call
puts "Hello world"
end
proc_test # calling proc_test prints nothing
这个有点类似循环中的continue
和 break