Ruby yield示例解释?

Jor*_*Lis 1 ruby yield block enumerable

我正在使用Ruby进行SaaS课程.在练习中,我被要求通过使用迭代器,块和产量来计算两个序列的笛卡尔积.

我最终得到了这个,通过纯粹的猜测和错误,它似乎工作.但我不确定如何.我似乎理解基本块和产量用法,但是这个?一点也不.

class CartProd
  include Enumerable
  def initialize(a,b)
        @a = a
        @b = b
  end
  def each
        @a.each{|ae|
                @b.each{|be|
                        yield [ae,be]
                }
        }
  end
end
Run Code Online (Sandbox Code Playgroud)

对我这样的菜鸟的一些解释好吗?

(PS:我将所需的课程名称更改为CartProd,因此人们通过Google搜索功能无法轻松找到答案)

man*_*oid 7

让我们一步一步地构建它.我们将通过从类上下文中取出它来简化一些事情.

对于这个例子,可以直观地将迭代器视为传统for循环的更强大的替代品.

所以首先这是一个for循环版本:

seq1 = (0..2)
seq2 = (0..2)
for x in seq1
  for y in seq2
    p [x,y] # shorthand for puts [x, y].inspect
  end
end  
Run Code Online (Sandbox Code Playgroud)

现在让我们用更多Ruby-idiomatic迭代器样式替换它,显式提供要执行的do...end块(即块):

seq1.each do |x|
  seq2.each do |y|
    p [x,y]
  end
end
Run Code Online (Sandbox Code Playgroud)

到目前为止,这么好,你已经打印出了笛卡尔积.现在您的作业也要求您使用yield.关键yield是"产生执行",即暂时将控制传递给另一个代码块(可选地传递一个或多个参数).

因此,虽然这个玩具示例并不是真的有必要,但不是直接打印上面的值,而是可以yield使用值,并让调用者提供一个接受该值的块并将其打印出来.

这看起来像这样:

 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

像这样可以调用:

prod (1..2), (1..2) do |prod| p prod end
Run Code Online (Sandbox Code Playgroud)

yield用品的产品用于内循环的每次运行,并且得到的值是通过由呼叫者提供的块打印.