Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby产量示例说明?_Ruby_Block_Yield_Enumerable - Fatal编程技术网

Ruby产量示例说明?

Ruby产量示例说明?,ruby,block,yield,enumerable,Ruby,Block,Yield,Enumerable,我正在用Ruby学习SaaS课程。在一个练习中,我被要求使用迭代器、块和产量计算两个序列的笛卡尔积 我的结论是,纯粹是猜测和错误,这似乎是可行的。但我不知道怎么做。我似乎理解基本块和产量用法,但是这个呢?一点也不 class CartProd include Enumerable def initialize(a,b) @a = a @b = b end def each @a.each{|ae| @

我正在用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
请给我这样的傻瓜解释一下好吗


(注:我将所需的类名改为CartProd,这样做的人就无法通过谷歌搜索找到答案)

你到底不明白什么?您已经创建了一个迭代器,可以生成所有可能的元素对。如果您通过
CartProd#每个
a块,它将执行
a.length*b.length
次。这就像在任何其他编程语言中将两个不同的
for
循环折叠成另一个循环一样

你到底不明白什么?您已经创建了一个迭代器,可以生成所有可能的元素对。如果您通过
CartProd#每个
a块,它将执行
a.length*b.length
次。这就像在任何其他编程语言中将两个不同的
for
循环折叠成另一个循环一样

yield只是将(yields)控制传递给作为方法调用一部分传入的代码块。yield关键字后面的值作为参数传递到块中。一旦块完成执行,它将返回控制

因此,在您的示例中,您可以这样称呼#每个:

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end
 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
prod (1..2), (1..2) do |prod| p prod end
这将输出每一对值。

yield只是将控制权传递给作为方法调用一部分传入的代码块。yield关键字后面的值作为参数传递到块中。一旦块完成执行,它将返回控制

因此,在您的示例中,您可以这样称呼#每个:

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end
 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
prod (1..2), (1..2) do |prod| p prod end

这将输出每对值。

让我们一步一步地构建它。我们将把它从类上下文中去掉,从而简化一些事情

对于本例,直观地认为迭代器是传统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  
现在,让我们用更多的Ruby惯用迭代器样式来替换它,显式地提供要执行的块(即
do…end
块):

到目前为止,很好,您已经打印出您的笛卡尔积。现在,您的作业要求您也使用
yield
yield
的要点是“yield execution”,即暂时将控制权传递给另一个代码块(可选地传递一个或多个参数)

因此,尽管在这个玩具示例中没有必要这样做,但您可以
生成
值,并让调用方提供一个接受该值的块并打印它,而不是像上面那样直接打印该值

可能是这样的:

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end
 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
prod (1..2), (1..2) do |prod| p prod end
可以这样称呼:

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end
 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
prod (1..2), (1..2) do |prod| p prod end

yield
为内部循环的每次运行提供产品,并且生成的值由调用方提供的块打印。

让我们一步一步地构建它。我们将把它从类上下文中去掉,从而简化一些事情

对于本例,直观地认为迭代器是传统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  
现在,让我们用更多的Ruby惯用迭代器样式来替换它,显式地提供要执行的块(即
do…end
块):

到目前为止,很好,您已经打印出您的笛卡尔积。现在,您的作业要求您也使用
yield
yield
的要点是“yield execution”,即暂时将控制权传递给另一个代码块(可选地传递一个或多个参数)

因此,尽管在这个玩具示例中没有必要这样做,但您可以
生成
值,并让调用方提供一个接受该值的块并打印它,而不是像上面那样直接打印该值

可能是这样的:

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end
 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
prod (1..2), (1..2) do |prod| p prod end
可以这样称呼:

CartProd.new([1, 2], [3, 4]).each do |pair|
  # control is yielded to this block
  p pair
  # control is returned at end of block
end
 def prod(seq1, seq2)
    seq1.each do |x|
      seq2.each do |y|
        yield [x,y]
      end
    end
  end
prod (1..2), (1..2) do |prod| p prod end


yield
为内部循环的每次运行提供产品,并且生成的值由调用者提供的块打印。

也许我不完全理解yield在那里做什么如果你的方法调用有一个块,它只是在执行一个块。您在yield调用中指定的任何参数都将传递给block。
yield[ae,be]
通知调用代码返回值为
[ae,be]
。仔细阅读有助于你理解这个例子是如何工作的。我想我现在明白了!因此,有一个名为each的块,由可枚举模块定义,用于完成任务。对吗?到目前为止,我所读到的关于收益率的用法是有道理的。也许我不明白收益率到底在做什么。如果你的方法调用有一个块,它只是在执行一个块。您在yield调用中指定的任何参数都将传递给block。
yield[ae,be]
通知调用代码返回值为
[ae,be]
。仔细阅读有助于你理解这个例子是如何工作的。我想我现在明白了!因此,有一个名为each的块,由可枚举模块定义,用于完成任务。对吗?这与我到目前为止所读到的有关yield用法的内容是有道理的。旁注:类变量@a和@b是有害的(试着用两个实例进行实验)。它们应该被替换为@a和@b。谢谢,我会更正的。所以@@定义了类变量和@instance变量。顺便说一句,
包含可枚举的
行是不必要的。@manzoid:除非CartProd本身是可枚举的。@muistooshort:这是一个很好的观点。如果您想混合使用可枚举设施,请确定。我认为上面提到的赋值有点不同:“使用迭代器、块和产量计算两个序列的笛卡尔乘积”,所以我认为最好保持简单