就是所谓的过程对象。 Proc 对象是将一组局部变量绑定到一起的代码块。一旦绑定,代码可以在不同的上下文环境中被调用且可保持对这些局部变量的访问。
Proc 是对块及其上下文环境 ( 局部变量的作用域 ) 进行对象化处理后得到的过程对象。你可以像使用匿名函数那样使用 Proc 。导入到 Proc 内的局部变量没有作用域的问题,也就是说, Proc 内的局部变量会让你得到动态局部变量的效果。
当我们希望向其它方法传递一块作为参数的代码,也就是说我们希望像处理数据一样处理代码时,你就应该想到 Proc 对象。
例如:
def gen_times(factor)
return Proc.new {|n| n*factor }
end
times3 = gen_times(3) # 3 赋值给 factor
times5 = gen_times(5)
times3.call(12) #=> 12 赋值给 n 结果为 12*3=36
times5.call(5) #=> 25
times3.call(times5.call(4)) #=> 60
若 Proc 中出现 return 或 retry 的话,会引发 LocalJumpError 异常。
类方法:
(1) Proc.new {|...| block } => a_proc Proc.new => a_proc 创建一个新的 Proc 对象来绑定当前上下文环境 context 。 Proc::new 在带有附加块的方法内部调用时,可以不带 block 块。在这种情况下,方法的块会被转发给 Proc 对象。即,把调用该方法的方法所带的块转换为 Proc 对象并将其返回。
例如:
def proc_from
Proc.new
end
proc = proc_from { "hello" }
proc.call #=> "hello"
在使用 Proc.new 时,若定义了 Proc#initialize 方法的话,就在对象初始化时调用该方法。
实例方法:
(1) prc.call(params,...) => obj prc[params,...] => obj 执行过程对象并将块内最后的表达式所计算出的值做为其结果返回。参数会被原样 ( 以遵守多重赋值原则 ) 赋值给块的参数。对于使用 Kernal.proc 创建的 Proc 对象,当传递给带有多个参数的 Proc 的参数数量有错误时,会生成一个错误。然而,使用 Proc.new 创建的 Proc 对象,会将额外的参数偷偷地丢弃。
例如:
a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]
a_proc[9, 1, 2, 3] #=> [9, 18, 27]
a_proc = Proc.new {|a,b| a}
a_proc.call(1,2,3) # 引发错误
produces:
prog.rb:5: wrong number of arguments (3 for 2) (ArgumentError)
from prog.rb:4:in `call'
from prog.rb:5