Подсказка:
Расширьте класс 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
Это то, что я собрал, и я не очень хорошо понимаю, как работают блоки / процессы в этом контексте, но каким-то образом я волшебным образом написал код, который прошел 3 из 4 тестов RSPEC.
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"]. Может кто-нибудь дать мне объяснение того, как или почему я получаю вложенный массив здесь?
Может ли кто-нибудь также дать мне объяснение того, как код выполняется, когда блок проходит через этот метод? Я не уверен, действительно ли мое условие «else» действительно необходимо в контексте тестов RSPEC. Меня обычно смущает концепция передачи блоков через самописные методы и то, как они взаимодействуют с самим методом.
Заранее спасибо!