Не уверен, что я добавляю что-то новое, но решил показать очень короткий код, который я хотел бы найти в ответах, чтобы быстро показать доступные варианты. Здесь @shelvacu говорит без перечислителя.
class Test
def initialize
@data = [1,2,3,4,5,6,7,8,9,0,11,12,12,13,14,15,16,172,28,38]
end
# approach 1
def each_y
@data.each{ |x| yield(x) }
end
#approach 2
def each_b(&block)
@data.each(&block)
end
end
Позволяет проверить производительность:
require 'benchmark'
test = Test.new
n=1000*1000*100
Benchmark.bm do |b|
b.report { 1000000.times{ test.each_y{|x| @foo=x} } }
b.report { 1000000.times{ test.each_b{|x| @foo=x} } }
end
Вот результат:
user system total real
1.660000 0.000000 1.660000 ( 1.669462)
1.830000 0.000000 1.830000 ( 1.831754)
Это означает, что yield
незначительно быстрее, чем & блокирует то, что мы уже знаем.
ОБНОВЛЕНИЕ : это IMO лучший способ создать каждый метод, который также заботится о возврате перечислителя
class Test
def each
if block_given?
@data.each{|x| yield(x)}
else
return @data.each
end
end
end