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搜索功能无法轻松找到答案)
让我们一步一步地构建它.我们将通过从类上下文中取出它来简化一些事情.
对于这个例子,可以直观地将迭代器视为传统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用品的产品用于内循环的每次运行,并且得到的值是通过由呼叫者提供的块打印.