玩转Ruby系列:玩转闭包(Block,Proc,lambda)
 
- 
博客分类:
 - Ruby/Rails
 
RubyF#BlogHTML
Block,lambda,Proc要好好理解下,在Ruby中很重要。
- Block块就是一个匿名函数,被调用的方法调用,在调用的方法里面通过field调用。Block主要用于迭代。
 
- arr=[1,2,3,4,5]
 - arr.each{|item|putsitem}
 
arr = [1,2,3,4,5]
arr.each{|item| puts item}
- Proc也是一个代码块,相当于过程吧
 
- a_proc=Proc.new{|a,*b|b.collect{|i|i*a}}
 - a_proc.call(9,1,2,3)#=>[9,18,27]
 
a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}
a_proc.call(9, 1, 2, 3)   #=> [9, 18, 27]
Proc.new新建一个Proc对象时,可以不带一个block,只是在定义Proc的方法上带一个block,这个block会变成属于Proc的。
- defproc_from
 - Proc.new
 - end
 - proc=proc_from{"hello"}
 - proc.call#=>"hello"
 
def proc_from
Proc.new
end
proc = proc_from { "hello" }
proc.call   #=> "hello"
Proc对象是与局部变量绑定的一个代码块。绑定之后,代码可以在不同的上下文中调用,并可以访问局部变量。
- defgen_times(factor)
 - returnProc.new{|n|n*factor}
 - end
 - times3=gen_times(3)
 - times5=gen_times(5)
 - times3.call(12)#=>36
 - times5.call(5)#=>25
 - times3.call(times5.call(4))#=>60
 
def gen_times(factor)
return Proc.new {|n| n*factor }
end
times3 = gen_times(3)
times5 = gen_times(5)
times3.call(12)               #=> 36
times5.call(5)                #=> 25
times3.call(times5.call(4))   #=> 60
- lambda也是匿名函数
 
- a_lambda=lambda{|a|putsa}
 - a_lambda.call("samsam")
 
a_lambda = lambda {|a| puts a}
a_lambda.call("samsam")
lambda返回的是一个Proc对象。
- a_lambda.class#=>Proc
 
a_lambda.class #=>Proc
lambda和Proc是一样的,除了Proc的return会跳出调用的方法,lambda则不会,它只是返回自己。
- deffoo
 - f=Proc.new{return"returnfromfoofrominsideproc"}
 - f.call#controlleavesfoohere
 - return"returnfromfoo"
 - end
 - defbar
 - f=lambda{return"returnfromlambda"}
 - putsf.call#controldoesnotleavebarhereprints"returnfromlambda"
 - return"returnfrombar"
 - end
 - putsfoo#prints"returnfromfoofrominsideproc"
 - putsbar#prints"returnfrombar"
 
def foo
f = Proc.new { return "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
def bar
f = lambda { return "return from lambda" }
puts f.call # control does not leave bar here  prints "return from lambda"
return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"   
参考:
http://www.ruby-doc.org/core/
http://www.artima.com/intv/closures.html
http://blackanger.blog.51cto.com/140924/83700