如何产生一个论点

How to yield an argument

此方法重现了 map 方法,以便更深入地了解 yield 的工作原理。

我研究了 yield 但我不明白为什么它以迭代元素作为参数。

我知道 yield 检索了一个块,但是这里 确切地 产生了什么,为什么它需要一个参数?

下面的代码是正确的:

def my_map(array)

  new_array = []
  array.each do |element|
    new_array << yield(element)
  end

  new_array
end

yield(element)element 传递给提供给 my_map 方法的块。

my_map([1,2,3]) {|element| element*2}

该块正在接收 element 作为您从 yield(element) 传来的输入。

考虑另一个例子来帮助说明:

def simple_yield(arg)
  yield(arg)
end

现在如果你这样做:

simple_yield(10){|x| puts x} #=> 10
simple_yield(){|x| puts x} #=>nil

yield(arg) 生成给定方法的块的参数。

如果您不通过 yield 方法将任何参数传递给块,则该参数将具有 nil 值,根据您在传递给使用 yield 的方法的块中所做的操作,这可能会导致错误。

def my_map(array)
  new_array = []

  array.each do |element|
    new_array << yield
  end

  new_array
end

my_map([1,2]) { |x| x } #=> [nil, nil]
my_map([1,2]) { |x| x + 1 } # will end up with undefined method `+' for nil:NilClass (NoMethodError)

yield 不会“检索一个块”,它会产生(可能有一个值,就像在这种情况下) 一个块,并且 "returns" 所述块返回的值。

它是 "taking" 迭代元素,因为 my_map 需要一个接收参数的块。

I tried to research yield a great deal but I can't figure out why in this case it is taking the iteration element as an argument.

yield 不接受争论。该块确实如此。 yield 生成块的值。

I know yield retrieves a block,

不,它将控制权(和价值)交给区块。

but what exactly is being yielded here and why does it take an argument?

element 引用的对象连同控制流都让渡给该块。

调用 yield 与调用 block.call 是一样的。所以 yield 用你的参数调用块。就是这样。

(您可以将块视为迷你方法。)

但是在您的方法中,您并未明确表示它接受块 (def my_map(array, &block)),但它隐含地接受了块。

所以你的实现,只是稍微重写,相当于:

def my_map(array, &block)  # added &block

  new_array = []
  array.each do |element|
    new_array << block.call(element)   # changed for block.call
  end

  new_array
end