提示:
扩展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”条件。通常,我对通过自写方法传递块的概念以及它们如何与方法本身交互感到困惑。
谢谢!
答案 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.