屈服於塊

你可以向你的方法傳送一個塊,它可以多次呼叫該塊。這可以通過傳送 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

事實上,foreacheachtimes 這樣的東西通常都是在課堂上實現的。

如果你想知道你是否被阻止,請使用 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 方法獲取具有員工姓名的物件。如果給出一個塊,那麼我們將把該名稱改為塊,否則我們只是將它推送到我們返回的陣列。