屈服于块
你可以向你的方法发送一个块,它可以多次调用该块。这可以通过发送 proc / lambda 等来完成,但是使用 yield
更容易,更快:
def simple(arg1,arg2)
puts "First we are here: #{arg1}"
yield
puts "Finally we are here: #{arg2}"
yield
end
simple('start','end') { puts "Now we are inside the yield" }
#> First we are here: start
#> Now we are inside the yield
#> Finally we are here: end
#> Now we are inside the yield
请注意,{ puts ... }
不在括号内,它隐含在后面。这也意味着我们只能拥有一个 yield
块。我们可以将参数传递给 yield
:
def simple(arg)
puts "Before yield"
yield(arg)
puts "After yield"
end
simple('Dave') { |name| puts "My name is #{name}" }
#> Before yield
#> My name is Dave
#> After yield
有了 yield,我们可以轻松地创建迭代器或任何适用于其他代码的函数:
def countdown(num)
num.times do |i|
yield(num-i)
end
end
countdown(5) { |i| puts "Call number #{i}" }
#> Call number 5
#> Call number 4
#> Call number 3
#> Call number 2
#> Call number 1
事实上,foreach
,each
和 times
这样的东西通常都是在课堂上实现的。
如果你想知道你是否被阻止,请使用 block_given?
:
class Employees
def names
ret = []
@employees.each do |emp|
if block_given?
yield(emp.name)
else
ret.push(emp.name)
end
end
ret
end
end
此示例假定 Employees
类具有 @employees
列表,可以使用 each
迭代以使用 name
方法获取具有员工姓名的对象。如果给出一个块,那么我们将把该名称改为块,否则我们只是将它推送到我们返回的数组。