block可以认为是一个一次性的、无法保存的Proc。
如果有两个地方要用到相同的block,就必须要重复两遍。而Proc可以把block保存下来,只需要调用两次即可。
先来看看怎么调用Proc,与block有什么不同。
class Array
def interate(code)
self.each_with_index do |n,i|
self[i] = code.call(n) * 10
end
end
end
array_1 = [1,3,5,7]
array_2 = [2,4,6,8]
myproc = Proc.new do |n|
n**2
end
array_1.interate(myproc)
array_2.interate(myproc)
p array_1 #=>[10,90,250,490]
p array_2 #=>[40,160,360,640]
p myproc.class #=>Proc
由上可见,myproc就是一个Proc,当array_1和array_2想要计算时,直接调用myproc即可,不需要再写一遍block中的代码。
当然,在调用Proc上,与block有一点不同,block是用yield
调用,而Proc是用call
方法调用。并且Proc会需要参数,而block则不用。看一下两者不同的地方
class Array
#block
def iterate!
self.each_with_index do |m,i|
self[i] = yield(m)
end
end
#Proc
def interate_1(code)
self.each_with_index do |n,i|
self[i] = code.call(n) * 10
end
end
end
#blcok
array = [1,2,3,4]
array.iterate! do |m|
m **=2
end
p array
#Proc
array_1 = [1,2,3,4]
myproc = Proc.new do |n|
n**2
end
array_1.interate_1(myproc)
p array_1
至于什么时候用block,什么时候用Proc。前人经验:
1、Block:方法把一个对象拆分成很多片段,并且你希望你的用户可以与这些片段做一些交互。
2、Block:希望自动运行多个语句,如数据库迁移(database migration)。
3、Proc:希望多次复用一段代码。
4、Proc:方法有一个或多个回调方法(callbacks)。