Alex学Ruby[详解 block和Proc对象 2]
2008-06-24 00:44
615 查看
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的符号。本文出自 “悟道集” 博客,请务必保留此出处http://blackanger.blog.51cto.com/140924/83701
本部分内容是基于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的符号。本文出自 “悟道集” 博客,请务必保留此出处http://blackanger.blog.51cto.com/140924/83701
相关文章推荐
- Alex学Ruby[详解 block和Proc对象]
- 详解Ruby中的代码块对象Proc
- Ruby学习笔记-Block, Proc and Lambda
- 比较C#中的委托和Ruby中的block对象
- Ruby中的block、proc、lambda区别总结
- ruby 中的Block,lambda,Proc
- Ruby中使用Block、Proc、lambda实现闭包
- ruby中的可调用对象--proc和lamdba
- Ruby系列:玩转闭包(Block,Proc,lambda)
- Ruby 面向对象知识详解
- 玩转Ruby系列:玩转闭包(Block,Proc,lambda)
- 【ruby】详解proc与lambda的区别
- ruby 的代码块 proc/lambda/method/block
- ruby中的 Proc、block说明
- What Is the Difference Between a Block, a Proc, and a Lambda in Ruby
- Ruby 中的 block、proc、lambda
- ruby中Block, Proc 和 Lambda 浅析
- Ruby 之 Block, Proc, Lambda 联系--区别,转载
- ruby的Proc和代码块(Block)
- iOS block 详解