1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
##
# chain.rb Enumerator::Chain class
# See Copyright Notice in mruby.h
module Enumerable
def chain(*args)
Enumerator::Chain.new(self, *args)
end
end
class Enumerator
def +(other)
Chain.new(self, other)
end
class Chain
include Enumerable
def initialize(*args)
@enums = args.freeze
@pos = -1
end
def each(&block)
return to_enum unless block
i = 0
while i < @enums.size
@pos = i
@enums[i].each(&block)
i += 1
end
self
end
def size
@enums.reduce(0) do |a, e|
return nil unless e.respond_to?(:size)
a + e.size
end
end
def rewind
while 0 <= @pos && @pos < @enums.size
e = @enums[@pos]
e.rewind if e.respond_to?(:rewind)
@pos -= 1
end
self
end
def +(other)
self.class.new(self, other)
end
def inspect
"#<#{self.class}: #{@enums.inspect}>"
end
end
end
|