Skip to content

Commit

Permalink
Add Enumerator::Product from marcandre/backports
Browse files Browse the repository at this point in the history
See marcandre/backports#192 for a few
small additional fixes incorporated here.
  • Loading branch information
headius committed Mar 5, 2024
1 parent c8cfb15 commit bf093d7
Showing 1 changed file with 52 additions and 1 deletion.
53 changes: 52 additions & 1 deletion core/src/main/ruby/jruby/kernel/enumerator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,55 @@ def __memo_set(yielder, value)
yielder.instance_variable_set :@__memo, value
end
end
end
end

# From https://github.com/marcandre/backports, MIT license
def Enumerator.product(*enums, **kwargs, &block)
if kwargs && !kwargs.empty?
raise ArgumentError.new("unknown keywords: " + kwargs.keys.map(&:inspect).join(", "))
end
Enumerator::Product.new(*enums).each(&block)
end

class Enumerator::Product < Enumerator
def initialize(*enums, **nil)
@__enums = enums
end

def each(&block)
return self unless block
__execute(block, [], @__enums)
end

def __execute(block, values, enums)
if enums.empty?
block.yield values
else
enum, *enums = enums
enum.each_entry do |val|
__execute(block, [*values, val], enums)
end
end
nil
end
private :__execute

def size
total_size = 1
@__enums.each do |enum|
return nil if !enum.respond_to?(:size)
size = enum.size
return size if size == nil || size == Float::INFINITY || size == -Float::INFINITY
return nil if !size.kind_of?(Integer) || size.equal?(Float::NAN)
total_size *= size
end
total_size
end

def rewind
@__enums.each do |enum|
enum.rewind if enum.respond_to?(:rewind)
end
self
end
end

0 comments on commit bf093d7

Please sign in to comment.