创建块对象

proc_create.rb

虽然默认情况下块(blocks)可能不是对象,但它们可以”变成”对象。有三种方式可以创建块对象并将它们分配给变量 - 具体方法如下:

  1. a = Proc.new{|x| x = x*10; puts(x) }
  2. b = lambda{|x| x = x*10; puts(x) }
  3. c = proc{|x| x.capitalize! }

请注意,在上述三种情况下,你最终都会创建一个 Proc 类的实例 - 这是 Ruby 为块提供的’对象包装器’(object wrapper)。让我们仔细看看创建 Proc 对象的三种方法。首先,你可以调用 Proc.new 创建一个对象,并将块作为参数传递给它:

3blocks.rb
  1. a = Proc.new{|x| x = x*10; puts(x)}

你可以通过 a 引用使用 Proc 类的 call 方法执行块中的代码,并将一个或多个参数(匹配块参数)传递给块;在上面的代码中,你可以传递一个整数,如 100,这将被分配给块变量 x

  1. a.call(100)

你也可以通过调用 lambdaproc 方法来创建 Proc 对象。这些方法(由 Kernel 类提供)是相同的。名称 lambda 取自 Scheme(Lisp)语言,是用于描述匿名方法或“闭包”(closure)的术语。

使用 Proc.new 创建 Proc 对象和使用 proclambda 方法创建 Proc 对象之间有一个重要的区别 - Proc.new 不检查传递给块的数字或参数是否与块参数的数量匹配 - 但 proclambda 会做检查:

proc_lamba.rb
  1. a = Proc.new{|x,y,z| x = y*z; puts(x) }
  2. a.call(2,5,10,100) # This is not an error
  3. b = lambda{|x,y,z| x = y*z; puts(x) }
  4. b.call(2,5,10,100) # This is an error
  5. puts('---Block #2---' )
  6. c = proc{|x,y,z| x = y*z; puts(x) }
  7. c.call(2,5,10,100) # This is an error
block_closure.rb