Alex学Ruby[详解 block和Proc对象 2]
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://blackanger.blog.51cto.com/140924/83701 |
Ruby Block Part Two 本部分内容是基于Ruby 1. 8. 7, 以后的系列都是1.8.7下测试。 例子1 : def return_using_procnew a_proc = Proc.new { return "Hi" } a_proc.call "Last line in the method" end => “ Hi” def return_using_lambda a_proc = lambda { return "Hi" } a_proc.call "Last line in the method" end => "Last line in the method" 以上例子可以看出lambda和Proc.new的区别, 用lambda的时候return会被劫持, 而Proc.new则不会。 例子2: def foo(proc_one,proc_two) proc_two.call proc_one.call end foo(lambda {p "Proc 1"}, lambda {p "Proc 2"}) => "Proc 2" "Proc 1" def foo(proc_one,proc_two) proc_one.call proc_two.call end foo(lambda {p "Proc 1"}, lambda {p "Proc 2"}) => "Proc 1" "Proc 2" 例子3: def foo(&my_block) my_block.call end foo { puts "Hi" } => Hi foo (lambda{ puts "Hi" }) => ArgumentError: wrong number of arguments (1 for 0) def foo(a,&my_block) a.call end foo (lambda{ puts "Hi" }) => Hi def foo(&my_block) my_block.call end foo { puts "Hi" } => Hi 例子4: 1.times do x = 5 closure = Proc.new {puts "In clsure value of x is #{x} end closure.call => In clsure value of x is 5 x = 1 puts x => 1 closure.call => In clsure value of x is 5 由此看出,闭包引用的变量是call这个proc对象时产生的变量,在外部修改其值是没用的。 例子5: class GreetingGenerator def initialize(greeting) @my_block = lambda {|name| puts "#{greeting}, #{name}"} end def greet(name) @my_block.call name end end frenchGreeting = GreetingGenerator.new “Bonjour” englishGreeting = GreetingGenerator.new “Hello” frenchGreeting.greet “TinTin” => Bonjour, TinTin englishGreeting.greet “Bunny” => Hello, Bunny 这你能看出来什么 ? 例子6: def repeat(n) n.times {yield} if block_given? end repeat(2) {puts "Hi"} def repeat2(n, &block) n.times {block.call} if block end repeat2(2) {puts "Hi2"} def repeat3(n,&block) n.times {yield} if block end repeat3(2){ puts "Hi3" } 这三种写法的目的是一样的。 例子7: print "(t)imes or (p)lus" times = gets print "number:" number = Integer(gets) if times =~ /^t/ calc = lambda {|n| n*number } else calc = lambda {|n| n + number} end p((1..10).collect(&calc).join(", ")) 这个例子也是闭包的概念。 例子8: words = %w(Daffy, Bugs, Alvin) upcase_words = words.map( &:upcase ) p upcase_words 例子的map(&:upcase)相当于map{ |x| x.upcase } 这个是如何实现的? 其实Symbol类内部实现了一个to_proc方法: class Symbol def to_proc lambda { |x,*args| x.send(self, *args) } end end map方法只接受代码块,通过使用&可传递proc,来代替显示的使用代码块。而这个时候&被应用于不是proc的对象,而传进来的本身是个符号对象(:&upcase),所以解释器自然而然的就会调用符号类的to_proc方法来得到一个proc。to_proc方法里的self引用的是对其调用了to_proc的符号。 本文出自 “{ :Alex Space => " Ruby Notes " }” 博客,请务必保留此出处http://blackanger.blog.51cto.com/140924/83701 本文出自 51CTO.COM技术博客 |



blackanger
博客统计信息
热门文章
最新评论
友情链接

