据说每个面试ruby的公司都会问这个问题。
block
依旧是从代码直接开始
ary = %w(bc def ek a)
ary1 = ary.sort do |i, j|
i.size <=> j.size
end
# ary1 a ek bc def
ary2 = ary.sort do |i, j|
i <=> j
end
# ary2 a bc def ek
上面两个用的是Array的sort函数。可把 block 视为函数(sort)的一个高阶参数
size_ = Proc.new do |i , j|
i.size <=> j.size
end
ary.sort(&size_)
上面这个例子中 size_ 是一个Proc对象的实例 &符号代表这个参数是一个 proc 。
Proc的new方法传入了一个高阶的block参数
yield 接上 下面给几个如何定义这些带高阶参数的函数的例子(By the way level)
class Array
def method_block
yield
end
def method_block_with(p)
yield(p)
end
def method_bock_param
w = 'windy'
yield(w)
end
end
ary = [1, 2, 3]
ary.method_block do
puts 'this is yield'
end #this is yield
ary.method_bock_param do |w|
puts 'yield ' + w
end #yield windy
ary.method_block_with('test') do |p|
puts p + ary.to_s
end #test[1, 2, 3]
lambda vs Proc
def methods(&code)
code.call
puts 'methods end'
end
a_proc = Proc.new do
puts "call Proc"
next
end
a_lambda = lambda do
puts 'call lambda'
return
end
methods(&a_proc) #call Proc ; methods end
methods(&a_lambda) #call lambda; methods end
def go
a = Proc.new do
puts 'Proc'
return
end
methods(&a)
puts 'end go'
end
def methods(&a)
puts "methods"
a.call
puts "end methods"
end
go # methods; Proc
def go
a = Proc.new do
puts 'Proc'
next
end
methods(&a)
puts 'end go'
end
def methods(&a)
puts "methods"
a.call
puts "end methods"
end
go # methods; Proc; end methods; end go;
- Proc 相当于是一个闭包(block ?) 保留定义代码时候的上下文环境 所以next即可(return 就是针对上下文的return了) 像是一个过程
- lambda 则更像是一个函数 。return 的返回值就是自己
- lambda 可以理解为一个特殊的Proc实例吧
- 匿名函数。还是当作一个变出来的变量来看吧。既然面向对象。那就是实例吧
- Proc.new创建的对象不会检查参数的数量,其它两种方法(proc | lambda)会;