本部分内容是基于Ruby 1. 8. 7, 以后的系列都是1.8.7下测试。
例子1 :
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:
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:
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:
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:
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:
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:
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:
upcase_words = words.map( &:upcase )
p upcase_words
例子的map(&:upcase)相当于map{ |x| x.upcase }
这个是如何实现的? 其实Symbol类内部实现了一个to_proc方法:
def to_proc
lambda { |x,*args| x.send(self, *args) }
end
end
map方法只接受代码块,通过使用&可传递proc,来代替显示的使用代码块。而这个时候&被应用于不是proc的对象,而传进来的本身是个符号对象(:&upcase),所以解释器自然而然的就会调用符号类的to_proc方法来得到一个proc。to_proc方法里的self引用的是对其调用了to_proc的符号。