数组中的块/处理返回数组说明

时间:2019-01-07 23:06:40

标签: ruby

提示: 扩展Array类以包括名为my_each的方法,该方法采用一个块,在该数组的每个元素上调用该块,然后返回原始数组。

class Array
  def my_each(&prc)
    if block_given?
      proc.call(self)
    else
      for i in (0..self.length-1)
        puts self[i]
      end
    end
    self
  end
end

这是我整理的内容,我对Blocks / Procs在这种情况下的工作方式没有很好的了解,但是我以某种方式神奇地编写了通过4个RSPEC测试中的3个的代码。

  describe "#my_each" do
    it "calls the block passed to it" do
      expect do |block|
        ["test array"].my_each(&block)
      end.to yield_control.once
    end

    it "yields each element to the block" do
      expect do |block|
        ["el1", "el2"].my_each(&block)
      end.to yield_successive_args("el1", "el2")
    end

    it "does NOT call the built-in #each method" do
      original_array = ["original array"]
      expect(original_array).not_to receive(:each)
      original_array.my_each {}
    end

    it "is chainable and returns the original array" do
      original_array = ["original array"]
      expect(original_array.my_each {}).to eq(original_array)
    end
  end

以上所有RSPEC测试都通过了,除了第二个测试通过,我的代码在期望使用[“ el1”,“ el2”]时返回[[“ el1”,“ el2”]]。有人可以给我解释一下如何或为什么在这里接收嵌套数组吗?

有人可以给我解释一下,当代码块通过此方法时代码是如何运行的吗?我不确定在RSPEC测试的情况下我是否真正需要“ else”条件。通常,我对通过自写方法传递块的概念以及它们如何与方法本身交互感到困惑。

谢谢!

2 个答案:

答案 0 :(得分:3)

在条件的第一部分,将整个数组传递给块:

if block_given?
  proc.call(self)
else
# ...

例如对于["el1", "el2"]数组,请执行proc.call(["el1", "el2"])。您在测试中期望的是两个连续的调用:

proc.call("el1")
proc.call("el2")

为此,您还需要在条件的第一部分使用循环,并在其中传递一个数组元素,而不是整个数组:

if block_given?
  for i in (0..self.length-1)
     proc.call(self[i])
  end
else
  for i in (0..self.length-1)
    puts self[i]
  end
end

答案 1 :(得分:0)

  proc.call(self)
罪魁祸首是

self是整个数组。

扩展Array类以包含名为my_each的方法

class Array
  def my_each
  end
end

需要一个块

#every method in ruby accepts a block, it is just ignored when not used (yielded to). Do nothing.

调用数组每个元素上的块,

class Array
  def my_each
    for element in self
      yield element
    end
  end
end

,然后返回原始数组。

# "for" loops do this. Do nothing. It should pass.