diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:19:16 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-24 09:53:24 +0000 |
commit | b5f8ee61a7f7e9bd291dd26b0585d03eb686c941 (patch) | |
tree | d4d31289c39fc00da064a825df13a0b98ce95b10 /web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator | |
parent | Adding upstream version 1.44.3. (diff) | |
download | netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.tar.xz netdata-b5f8ee61a7f7e9bd291dd26b0585d03eb686c941.zip |
Adding upstream version 1.46.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator')
3 files changed, 0 insertions, 1198 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake deleted file mode 100644 index 8757a15ea..000000000 --- a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrbgem.rake +++ /dev/null @@ -1,7 +0,0 @@ -MRuby::Gem::Specification.new('mruby-enumerator') do |spec| - spec.license = 'MIT' - spec.author = 'mruby developers' - spec.add_dependency('mruby-fiber', :core => 'mruby-fiber') - spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' - spec.summary = 'Enumerator class' -end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb deleted file mode 100644 index 1e77af369..000000000 --- a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ /dev/null @@ -1,645 +0,0 @@ -## -# enumerator.rb Enumerator class -# See Copyright Notice in mruby.h - -## -# A class which allows both internal and external iteration. -# -# An Enumerator can be created by the following methods. -# - {Kernel#to_enum} -# - {Kernel#enum_for} -# - {Enumerator#initialize Enumerator.new} -# -# Most methods have two forms: a block form where the contents -# are evaluated for each item in the enumeration, and a non-block form -# which returns a new Enumerator wrapping the iteration. -# -# enumerator = %w(one two three).each -# puts enumerator.class # => Enumerator -# -# enumerator.each_with_object("foo") do |item, obj| -# puts "#{obj}: #{item}" -# end -# -# # foo: one -# # foo: two -# # foo: three -# -# enum_with_obj = enumerator.each_with_object("foo") -# puts enum_with_obj.class # => Enumerator -# -# enum_with_obj.each do |item, obj| -# puts "#{obj}: #{item}" -# end -# -# # foo: one -# # foo: two -# # foo: three -# -# This allows you to chain Enumerators together. For example, you -# can map a list's elements to strings containing the index -# and the element as a string via: -# -# puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" } -# # => ["0:foo", "1:bar", "2:baz"] -# -# An Enumerator can also be used as an external iterator. -# For example, Enumerator#next returns the next value of the iterator -# or raises StopIteration if the Enumerator is at the end. -# -# e = [1,2,3].each # returns an enumerator object. -# puts e.next # => 1 -# puts e.next # => 2 -# puts e.next # => 3 -# puts e.next # raises StopIteration -# -# You can use this to implement an internal iterator as follows: -# -# def ext_each(e) -# while true -# begin -# vs = e.next_values -# rescue StopIteration -# return $!.result -# end -# y = yield(*vs) -# e.feed y -# end -# end -# -# o = Object.new -# -# def o.each -# puts yield -# puts yield(1) -# puts yield(1, 2) -# 3 -# end -# -# # use o.each as an internal iterator directly. -# puts o.each {|*x| puts x; [:b, *x] } -# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 -# -# # convert o.each to an external iterator for -# # implementing an internal iterator. -# puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] } -# # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 -# -class Enumerator - include Enumerable - - ## - # @overload initialize(size = nil, &block) - # @overload initialize(obj, method = :each, *args) - # - # Creates a new Enumerator object, which can be used as an - # Enumerable. - # - # In the first form, iteration is defined by the given block, in - # which a "yielder" object, given as block parameter, can be used to - # yield a value by calling the +yield+ method (aliased as +<<+): - # - # fib = Enumerator.new do |y| - # a = b = 1 - # loop do - # y << a - # a, b = b, a + b - # end - # end - # - # p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] - # - def initialize(obj=nil, meth=:each, *args, &block) - if block - obj = Generator.new(&block) - else - raise ArgumentError unless obj - end - if @obj and !self.respond_to?(meth) - raise NoMethodError, "undefined method #{meth}" - end - - @obj = obj - @meth = meth - @args = args.dup - @fib = nil - @dst = nil - @lookahead = nil - @feedvalue = nil - @stop_exc = false - end - attr_accessor :obj, :meth, :args, :fib - private :obj, :meth, :args, :fib - - def initialize_copy(obj) - raise TypeError, "can't copy type #{obj.class}" unless obj.kind_of? Enumerator - raise TypeError, "can't copy execution context" if obj.fib - @obj = obj.obj - @meth = obj.meth - @args = obj.args - @fib = nil - @lookahead = nil - @feedvalue = nil - self - end - - ## - # call-seq: - # e.with_index(offset = 0) {|(*args), idx| ... } - # e.with_index(offset = 0) - # - # Iterates the given block for each element with an index, which - # starts from +offset+. If no block is given, returns a new Enumerator - # that includes the index, starting from +offset+ - # - # +offset+:: the starting index to use - # - def with_index(offset=0, &block) - return to_enum :with_index, offset unless block - - offset = if offset.nil? - 0 - elsif offset.respond_to?(:to_int) - offset.to_int - else - raise TypeError, "no implicit conversion of #{offset.class} into Integer" - end - - n = offset - 1 - enumerator_block_call do |*i| - n += 1 - block.call i.__svalue, n - end - end - - ## - # call-seq: - # e.each_with_index {|(*args), idx| ... } - # e.each_with_index - # - # Same as Enumerator#with_index(0), i.e. there is no starting offset. - # - # If no block is given, a new Enumerator is returned that includes the index. - # - def each_with_index(&block) - with_index(0, &block) - end - - ## - # call-seq: - # e.each_with_object(obj) {|(*args), obj| ... } - # e.each_with_object(obj) - # e.with_object(obj) {|(*args), obj| ... } - # e.with_object(obj) - # - # Iterates the given block for each element with an arbitrary object, +obj+, - # and returns +obj+ - # - # If no block is given, returns a new Enumerator. - # - # @example - # to_three = Enumerator.new do |y| - # 3.times do |x| - # y << x - # end - # end - # - # to_three_with_string = to_three.with_object("foo") - # to_three_with_string.each do |x,string| - # puts "#{string}: #{x}" - # end - # - # # => foo:0 - # # => foo:1 - # # => foo:2 - # - def with_object(object, &block) - return to_enum(:with_object, object) unless block - - enumerator_block_call do |i| - block.call [i,object] - end - object - end - - def inspect - return "#<#{self.class}: uninitialized>" unless @obj - - if @args && @args.size > 0 - args = @args.join(", ") - "#<#{self.class}: #{@obj}:#{@meth}(#{args})>" - else - "#<#{self.class}: #{@obj}:#{@meth}>" - end - end - - ## - # call-seq: - # enum.each { |elm| block } -> obj - # enum.each -> enum - # enum.each(*appending_args) { |elm| block } -> obj - # enum.each(*appending_args) -> an_enumerator - # - # Iterates over the block according to how this Enumerator was constructed. - # If no block and no arguments are given, returns self. - # - # === Examples - # - # "Hello, world!".scan(/\w+/) #=> ["Hello", "world"] - # "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"] - # "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"] - # - # obj = Object.new - # - # def obj.each_arg(a, b=:b, *rest) - # yield a - # yield b - # yield rest - # :method_returned - # end - # - # enum = obj.to_enum :each_arg, :a, :x - # - # enum.each.to_a #=> [:a, :x, []] - # enum.each.equal?(enum) #=> true - # enum.each { |elm| elm } #=> :method_returned - # - # enum.each(:y, :z).to_a #=> [:a, :x, [:y, :z]] - # enum.each(:y, :z).equal?(enum) #=> false - # enum.each(:y, :z) { |elm| elm } #=> :method_returned - # - def each(*argv, &block) - obj = self - if 0 < argv.length - obj = self.dup - args = obj.args - if !args.empty? - args = args.dup - args.concat argv - else - args = argv.dup - end - obj.args = args - end - return obj unless block - enumerator_block_call(&block) - end - - def enumerator_block_call(&block) - @obj.__send__ @meth, *@args, &block - end - private :enumerator_block_call - - ## - # call-seq: - # e.next -> object - # - # Returns the next object in the enumerator, and move the internal position - # forward. When the position reached at the end, StopIteration is raised. - # - # === Example - # - # a = [1,2,3] - # e = a.to_enum - # p e.next #=> 1 - # p e.next #=> 2 - # p e.next #=> 3 - # p e.next #raises StopIteration - # - # Note that enumeration sequence by +next+ does not affect other non-external - # enumeration methods, unless the underlying iteration methods itself has - # side-effect - # - def next - next_values.__svalue - end - - ## - # call-seq: - # e.next_values -> array - # - # Returns the next object as an array in the enumerator, and move the - # internal position forward. When the position reached at the end, - # StopIteration is raised. - # - # This method can be used to distinguish <code>yield</code> and <code>yield - # nil</code>. - # - # === Example - # - # o = Object.new - # def o.each - # yield - # yield 1 - # yield 1, 2 - # yield nil - # yield [1, 2] - # end - # e = o.to_enum - # p e.next_values - # p e.next_values - # p e.next_values - # p e.next_values - # p e.next_values - # e = o.to_enum - # p e.next - # p e.next - # p e.next - # p e.next - # p e.next - # - # ## yield args next_values next - # # yield [] nil - # # yield 1 [1] 1 - # # yield 1, 2 [1, 2] [1, 2] - # # yield nil [nil] nil - # # yield [1, 2] [[1, 2]] [1, 2] - # - # Note that +next_values+ does not affect other non-external enumeration - # methods unless underlying iteration method itself has side-effect - # - def next_values - if @lookahead - vs = @lookahead - @lookahead = nil - return vs - end - raise @stop_exc if @stop_exc - - curr = Fiber.current - - if !@fib || !@fib.alive? - @dst = curr - @fib = Fiber.new do - result = each do |*args| - feedvalue = nil - Fiber.yield args - if @feedvalue - feedvalue = @feedvalue - @feedvalue = nil - end - feedvalue - end - @stop_exc = StopIteration.new "iteration reached an end" - @stop_exc.result = result - Fiber.yield nil - end - @lookahead = nil - end - - vs = @fib.resume curr - if @stop_exc - @fib = nil - @dst = nil - @lookahead = nil - @feedvalue = nil - raise @stop_exc - end - vs - end - - ## - # call-seq: - # e.peek -> object - # - # Returns the next object in the enumerator, but doesn't move the internal - # position forward. If the position is already at the end, StopIteration - # is raised. - # - # === Example - # - # a = [1,2,3] - # e = a.to_enum - # p e.next #=> 1 - # p e.peek #=> 2 - # p e.peek #=> 2 - # p e.peek #=> 2 - # p e.next #=> 2 - # p e.next #=> 3 - # p e.next #raises StopIteration - # - def peek - peek_values.__svalue - end - - ## - # call-seq: - # e.peek_values -> array - # - # Returns the next object as an array, similar to Enumerator#next_values, but - # doesn't move the internal position forward. If the position is already at - # the end, StopIteration is raised. - # - # === Example - # - # o = Object.new - # def o.each - # yield - # yield 1 - # yield 1, 2 - # end - # e = o.to_enum - # p e.peek_values #=> [] - # e.next - # p e.peek_values #=> [1] - # p e.peek_values #=> [1] - # e.next - # p e.peek_values #=> [1, 2] - # e.next - # p e.peek_values # raises StopIteration - # - def peek_values - if @lookahead.nil? - @lookahead = next_values - end - @lookahead.dup - end - - ## - # call-seq: - # e.rewind -> e - # - # Rewinds the enumeration sequence to the beginning. - # - # If the enclosed object responds to a "rewind" method, it is called. - # - def rewind - @obj.rewind if @obj.respond_to? :rewind - @fib = nil - @dst = nil - @lookahead = nil - @feedvalue = nil - @stop_exc = false - self - end - - ## - # call-seq: - # e.feed obj -> nil - # - # Sets the value to be returned by the next yield inside +e+. - # - # If the value is not set, the yield returns nil. - # - # This value is cleared after being yielded. - # - # # Array#map passes the array's elements to "yield" and collects the - # # results of "yield" as an array. - # # Following example shows that "next" returns the passed elements and - # # values passed to "feed" are collected as an array which can be - # # obtained by StopIteration#result. - # e = [1,2,3].map - # p e.next #=> 1 - # e.feed "a" - # p e.next #=> 2 - # e.feed "b" - # p e.next #=> 3 - # e.feed "c" - # begin - # e.next - # rescue StopIteration - # p $!.result #=> ["a", "b", "c"] - # end - # - # o = Object.new - # def o.each - # x = yield # (2) blocks - # p x # (5) => "foo" - # x = yield # (6) blocks - # p x # (8) => nil - # x = yield # (9) blocks - # p x # not reached w/o another e.next - # end - # - # e = o.to_enum - # e.next # (1) - # e.feed "foo" # (3) - # e.next # (4) - # e.next # (7) - # # (10) - # - def feed(value) - raise TypeError, "feed value already set" if @feedvalue - @feedvalue = value - nil - end - - # just for internal - class Generator - include Enumerable - def initialize(&block) - raise TypeError, "wrong argument type #{self.class} (expected Proc)" unless block.kind_of? Proc - - @proc = block - end - - def each(*args, &block) - args.unshift Yielder.new(&block) - @proc.call(*args) - end - end - - # just for internal - class Yielder - def initialize(&block) - raise LocalJumpError, "no block given" unless block - - @proc = block - end - - def yield(*args) - @proc.call(*args) - end - - def << *args - self.yield(*args) - self - end - end -end - -module Kernel - ## - # call-seq: - # obj.to_enum(method = :each, *args) -> enum - # obj.enum_for(method = :each, *args) -> enum - # obj.to_enum(method = :each, *args) {|*args| block} -> enum - # obj.enum_for(method = :each, *args){|*args| block} -> enum - # - # Creates a new Enumerator which will enumerate by calling +method+ on - # +obj+, passing +args+ if any. - # - # If a block is given, it will be used to calculate the size of - # the enumerator without the need to iterate it (see Enumerator#size). - # - # === Examples - # - # str = "xyz" - # - # enum = str.enum_for(:each_byte) - # enum.each { |b| puts b } - # # => 120 - # # => 121 - # # => 122 - # - # # protect an array from being modified by some_method - # a = [1, 2, 3] - # some_method(a.to_enum) - # - # It is typical to call to_enum when defining methods for - # a generic Enumerable, in case no block is passed. - # - # Here is such an example, with parameter passing and a sizing block: - # - # module Enumerable - # # a generic method to repeat the values of any enumerable - # def repeat(n) - # raise ArgumentError, "#{n} is negative!" if n < 0 - # unless block_given? - # return to_enum(__method__, n) do # __method__ is :repeat here - # sz = size # Call size and multiply by n... - # sz * n if sz # but return nil if size itself is nil - # end - # end - # each do |*val| - # n.times { yield *val } - # end - # end - # end - # - # %i[hello world].repeat(2) { |w| puts w } - # # => Prints 'hello', 'hello', 'world', 'world' - # enum = (1..14).repeat(3) - # # => returns an Enumerator when called without a block - # enum.first(4) # => [1, 1, 1, 2] - # - def to_enum(meth=:each, *args) - Enumerator.new self, meth, *args - end - alias enum_for to_enum -end - -module Enumerable - # use Enumerator to use infinite sequence - def zip(*arg) - ary = [] - arg = arg.map{|a|a.each} - i = 0 - self.each do |*val| - a = [] - a.push(val.__svalue) - idx = 0 - while idx < arg.size - begin - a.push(arg[idx].next) - rescue StopIteration - a.push(nil) - end - idx += 1 - end - ary.push(a) - i += 1 - end - ary - end -end diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb deleted file mode 100644 index 763cd36e2..000000000 --- a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +++ /dev/null @@ -1,546 +0,0 @@ -@obj = Object.new -class << @obj - include Enumerable - def foo *a - a.each { |x| yield x } - end -end - -assert 'Enumerator' do - assert_equal Class, Enumerator.class -end - -assert 'Enumerator' do - assert_equal Object, Enumerator.superclass -end - -assert 'Enumerator.new' do - assert_equal [0,1,2], 3.times.map{|i| i}.sort - assert_equal [:x,:y,:z], [:x,:y,:z].each.map{|i| i}.sort - assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort - assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a - assert_equal [1,2,3], Enumerator.new(@obj, :foo, 1,2,3).to_a - assert_equal [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3) - assert_raise(ArgumentError) { Enumerator.new } - enum = @obj.to_enum - assert_raise(NoMethodError) { enum.each {} } - - # examples - fib = Enumerator.new do |y| - a = b = 1 - loop do - y << a - a, b = b, a + b - end - end - assert_equal fib.take(10), [1,1,2,3,5,8,13,21,34,55] -end - -assert 'Enumerator#initialize_copy' do - assert_equal [1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a - e = @obj.to_enum :foo, 1, 2, 3 - assert_nothing_raised { assert_equal(1, e.next) } - assert_raise(TypeError) { e.dup } - - e = Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.dup - assert_nothing_raised { assert_equal(1, e.next) } - assert_raise(TypeError) { e.dup } -end - -assert 'Enumerator#with_index' do - assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a) - assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a) - a = [] - @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i } - assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a -end - -assert 'Enumerator#with_index nonnum offset' do - s = Object.new - def s.to_int; 1 end - assert_equal([[1,1],[2,2],[3,3]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a) -end - -assert 'Enumerator#with_index string offset' do - assert_raise(TypeError){ @obj.to_enum(:foo, 1, 2, 3).with_index('1').to_a } -end - -assert 'Enumerator#each_with_index' do - assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).each_with_index.to_a) - a = [] - @obj.to_enum(:foo, 1, 2, 3).each_with_index {|*i| a << i} - assert_equal([[1, 0], [2, 1], [3, 2]], a) -end - -assert 'Enumerator#with_object' do - obj = [0, 1] - ret = (1..10).each.with_object(obj) {|i, memo| - memo[0] += i - memo[1] *= i - } - assert_true(obj.equal?(ret)) - assert_equal([55, 3628800], ret) -end - -assert 'Enumerator#with_object arguments' do - to_three = Enumerator.new do |y| - 3.times do |x| - y << x - end - end - - a = [] - to_three_with_string = to_three.with_object("foo") - to_three_with_string.each do |x,string| - a << "#{string}:#{x}" - end - assert_equal ["foo:0","foo:1","foo:2"], a -end - -assert 'Enumerator#inspect' do - e = (0..10).each - assert_equal("#<Enumerator: 0..10:each>", e.inspect) - e = Enumerator.new("FooObject", :foo, 1) - assert_equal("#<Enumerator: FooObject:foo(1)>", e.inspect) - e = Enumerator.new("FooObject", :foo, 1, 2, 3) - assert_equal("#<Enumerator: FooObject:foo(1, 2, 3)>", e.inspect) -end - -assert 'Enumerator#each' do - o = Object.new - def o.each(ary) - ary << 1 - yield - end - ary = [] - e = o.to_enum.each(ary) - e.next - assert_equal([1], ary) -end - -assert 'Enumerator#each arguments' do - obj = Object.new - - def obj.each_arg(a, b=:b, *rest) - yield a - yield b - yield rest - :method_returned - end - - enum = obj.to_enum :each_arg, :a, :x - - assert_equal [:a, :x, []], enum.each.to_a - assert_true enum.each.equal?(enum) - assert_equal :method_returned, enum.each { |elm| elm } - - assert_equal [:a, :x, [:y, :z]], enum.each(:y, :z).to_a - assert_false enum.each(:y, :z).equal?(enum) - assert_equal :method_returned, enum.each(:y, :z) { |elm| elm } -end - -assert 'Enumerator#next' do - e = 3.times - 3.times { |i| - assert_equal i, e.next - } - assert_raise(StopIteration) { e.next } -end - -assert 'Enumerator#next_values' do - o = Object.new - def o.each - yield - yield 1 - yield 1, 2 - end - e = o.to_enum - assert_equal nil, e.next - assert_equal 1, e.next - assert_equal [1,2], e.next - e = o.to_enum - assert_equal [], e.next_values - assert_equal [1], e.next_values - assert_equal [1,2], e.next_values -end - -assert 'Enumerator#peek' do - a = [1] - e = a.each - assert_equal 1, e.peek - assert_equal 1, e.peek - assert_equal 1, e.next - assert_raise(StopIteration) { e.peek } - assert_raise(StopIteration) { e.peek } -end - -assert 'Enumerator#peek modify' do - o = Object.new - def o.each - yield 1,2 - end - e = o.to_enum - a = e.peek - a << 3 - assert_equal([1,2], e.peek) -end - -assert 'Enumerator#peek_values' do - o = Object.new - def o.each - yield - yield 1 - yield 1, 2 - end - e = o.to_enum - assert_equal nil, e.peek - assert_equal nil, e.next - assert_equal 1, e.peek - assert_equal 1, e.next - assert_equal [1,2], e.peek - assert_equal [1,2], e.next - e = o.to_enum - assert_equal [], e.peek_values - assert_equal [], e.next_values - assert_equal [1], e.peek_values - assert_equal [1], e.next_values - assert_equal [1,2], e.peek_values - assert_equal [1,2], e.next_values - e = o.to_enum - assert_equal [], e.peek_values - assert_equal nil, e.next - assert_equal [1], e.peek_values - assert_equal 1, e.next - assert_equal [1,2], e.peek_values - assert_equal [1,2], e.next - e = o.to_enum - assert_equal nil, e.peek - assert_equal [], e.next_values - assert_equal 1, e.peek - assert_equal [1], e.next_values - assert_equal [1,2], e.peek - assert_equal [1,2], e.next_values -end - -assert 'Enumerator#peek_values modify' do - o = Object.new - def o.each - yield 1,2 - end - e = o.to_enum - a = e.peek_values - a << 3 - assert_equal [1,2], e.peek -end - -assert 'Enumerator#feed' do - o = Object.new - def o.each(ary) - ary << yield - ary << yield - ary << yield - end - ary = [] - e = o.to_enum :each, ary - e.next - e.feed 1 - e.next - e.feed 2 - e.next - e.feed 3 - assert_raise(StopIteration) { e.next } - assert_equal [1,2,3], ary -end - -assert 'Enumerator#feed mixed' do - o = Object.new - def o.each(ary) - ary << yield - ary << yield - ary << yield - end - ary = [] - e = o.to_enum :each, ary - e.next - e.feed 1 - e.next - e.next - e.feed 3 - assert_raise(StopIteration) { e.next } - assert_equal [1,nil,3], ary -end - -assert 'Enumerator#feed twice' do - o = Object.new - def o.each(ary) - ary << yield - ary << yield - ary << yield - end - ary = [] - e = o.to_enum :each, ary - e.feed 1 - assert_raise(TypeError) { e.feed 2 } -end - -assert 'Enumerator#feed before first next' do - o = Object.new - def o.each(ary) - ary << yield - ary << yield - ary << yield - end - ary = [] - e = o.to_enum :each, ary - e.feed 1 - e.next - e.next - assert_equal [1], ary -end - -assert 'Enumerator#feed yielder' do - x = nil - e = Enumerator.new {|y| x = y.yield; 10 } - e.next - e.feed 100 - assert_raise(StopIteration) { e.next } - assert_equal 100, x -end - -assert 'Enumerator#rewind' do - e = @obj.to_enum(:foo, 1, 2, 3) - assert_equal 1, e.next - assert_equal 2, e.next - e.rewind - assert_equal 1, e.next - assert_equal 2, e.next - assert_equal 3, e.next - assert_raise(StopIteration) { e.next } -end - -assert 'Enumerator#rewind clear feed' do - o = Object.new - def o.each(ary) - ary << yield - ary << yield - ary << yield - end - ary = [] - e = o.to_enum(:each, ary) - e.next - e.feed 1 - e.next - e.feed 2 - e.rewind - e.next - e.next - assert_equal([1,nil], ary) -end - -assert 'Enumerator#rewind clear' do - o = Object.new - def o.each(ary) - ary << yield - ary << yield - ary << yield - end - ary = [] - e = o.to_enum :each, ary - e.next - e.feed 1 - e.next - e.feed 2 - e.rewind - e.next - e.next - assert_equal [1,nil], ary -end - -assert 'Enumerator::Generator' do - # note: Enumerator::Generator is a class just for internal - g = Enumerator::Generator.new {|y| y << 1 << 2 << 3; :foo } - g2 = g.dup - a = [] - assert_equal(:foo, g.each {|x| a << x }) - assert_equal([1, 2, 3], a) - a = [] - assert_equal(:foo, g2.each {|x| a << x }) - assert_equal([1, 2, 3], a) -end - -assert 'Enumerator::Generator args' do - g = Enumerator::Generator.new {|y, x| y << 1 << 2 << 3; x } - a = [] - assert_equal(:bar, g.each(:bar) {|x| a << x }) - assert_equal([1, 2, 3], a) -end - -assert 'Enumerator::Yielder' do - # note: Enumerator::Yielder is a class just for internal - a = [] - y = Enumerator::Yielder.new {|x| a << x } - assert_equal(y, y << 1 << 2 << 3) - assert_equal([1, 2, 3], a) - - a = [] - y = Enumerator::Yielder.new {|x| a << x } - assert_equal([1], y.yield(1)) - assert_equal([1, 2], y.yield(2)) - assert_equal([1, 2, 3], y.yield(3)) - - assert_raise(LocalJumpError) { Enumerator::Yielder.new } -end - -assert 'next after StopIteration' do - a = [1] - e = a.each - assert_equal(1, e.next) - assert_raise(StopIteration) { e.next } - assert_raise(StopIteration) { e.next } - e.rewind - assert_equal(1, e.next) - assert_raise(StopIteration) { e.next } - assert_raise(StopIteration) { e.next } -end - -assert 'gc' do - assert_nothing_raised do - 1.times do - foo = [1,2,3].to_enum - GC.start - end - GC.start - end -end - -assert 'nested iteration' do - def (o = Object.new).each - yield :ok1 - yield [:ok2, :x].each.next - end - e = o.to_enum - assert_equal :ok1, e.next - assert_equal :ok2, e.next - assert_raise(StopIteration) { e.next } -end - -assert 'Kernel#to_enum' do - assert_equal Enumerator, [].to_enum.class - assert_raise(ArgumentError){ nil.to_enum } -end - -assert 'modifying existing methods' do - assert_equal Enumerator, loop.class - e = 3.times - i = 0 - loop_ret = loop { - assert_equal i, e.next - i += 1 - } -end - -assert 'Integral#times' do - a = 3 - b = a.times - c = [] - b.with_object(c) do |i, obj| - obj << i - end - assert_equal 3, a - assert_equal Enumerator, b.class - assert_equal [0,1,2], c -end - -assert 'Enumerable#each_with_index' do - assert_equal [['a',0],['b',1],['c',2]], ['a','b','c'].each_with_index.to_a -end - -assert 'Enumerable#map' do - a = [1,2,3] - b = a.map - c = b.with_index do |i, index| - [i*i, index*index] - end - assert_equal [1,2,3], a - assert_equal [[1,0],[4,1],[9,4]], c -end - -assert 'Enumerable#find_all' do - assert_equal [[3,4]], [[1,2],[3,4],[5,6]].find_all.each{ |i| i[1] == 4 } -end - -assert 'Array#each_index' do - a = [1,2,3] - b = a.each_index - c = [] - b.with_index do |index1,index2| - c << [index1+2,index2+5] - end - assert_equal [1,2,3], a - assert_equal [[2,5],[3,6],[4,7]], c -end - -assert 'Array#map!' do - a = [1,2,3] - b = a.map! - b.with_index do |i, index| - [i*i, index*index] - end - assert_equal [[1,0],[4,1],[9,4]], a -end - -assert 'Hash#each' do - a = {a:1,b:2} - b = a.each - c = [] - b.each do |k,v| - c << [k,v] - end - assert_equal [[:a,1], [:b,2]], c.sort -end - -assert 'Hash#each_key' do - assert_equal [:a,:b], {a:1,b:2}.each_key.to_a.sort -end - -assert 'Hash#each_value' do - assert_equal [1,2], {a:1,b:2}.each_value.to_a.sort -end - -assert 'Hash#select' do - h = {1=>2,3=>4,5=>6} - hret = h.select.with_index {|a,b| a[1] == 4} - assert_equal({3=>4}, hret) - assert_equal({1=>2,3=>4,5=>6}, h) -end - -assert 'Hash#select!' do - h = {1=>2,3=>4,5=>6} - hret = h.select!.with_index {|a,b| a[1] == 4} - assert_equal h, hret - assert_equal({3=>4}, h) -end - -assert 'Hash#reject' do - h = {1=>2,3=>4,5=>6} - hret = h.reject.with_index {|a,b| a[1] == 4} - assert_equal({1=>2,5=>6}, hret) - assert_equal({1=>2,3=>4,5=>6}, h) -end - -assert 'Hash#reject!' do - h = {1=>2,3=>4,5=>6} - hret = h.reject!.with_index {|a,b| a[1] == 4} - assert_equal h, hret - assert_equal({1=>2,5=>6}, h) -end - -assert 'Range#each' do - a = (1..5) - b = a.each - c = [] - b.each do |i| - c << i - end - assert_equal [1,2,3,4,5], c -end |