1unless Enumerator.method_defined? :product
2 if RUBY_VERSION >= '2.7'
3 instance_eval <<-'EOT', __FILE__, __LINE__ + 1
4 def Enumerator.product(*enums, **kwargs, &block)
5 if kwargs && !kwargs.empty?
6 raise ArgumentError, "unknown keywords: #{kwargs.keys.map(&:inspect).join(', ')}"
7 end
8 product = Enumerator::Product.new(*enums)
9
10 if block_given?
11 product.each(&block)
12 return nil
13 end
14
15 product
16 end
17 EOT
18 else
19 def Enumerator.product(*enums, &block)
20 kwargs = enums[-1]
21 if kwargs.is_a?(Hash) && !kwargs.empty?
22 raise ArgumentError, "unknown keywords: #{kwargs.keys.map(&:inspect).join(', ')}"
23 end
24 product = Enumerator::Product.new(*enums)
25
26 if block_given?
27 product.each(&block)
28 return nil
29 end
30
31 product
32 end
33 end
34
35 class Enumerator::Product < Enumerator
36 if RUBY_VERSION >= '2.7'
37 module_eval <<-EOT, __FILE__, __LINE__ + 1
38 def initialize(*enums, **nil)
39 @__enums = enums
40 end
41 EOT
42 else
43 # rubocop:disable Lint/MissingSuper
44 def initialize(*enums)
45 @__enums = enums
46 self
47 end
48 # rubocop:enable Lint/MissingSuper
49 end
50
51 def each(&block)
52 return self unless block
53 __execute(block, [], @__enums)
54 self
55 end
56
57 def __execute(block, values, enums)
58 if enums.empty?
59 block.yield values
60 else
…lines 61–68 unchanged (8 lines)
69
70 def size
71 total_size = 1
72 @__enums.each do |enum|
73 return nil unless enum.respond_to?(:size)
74 size = enum.size
75 return size if size == 0 || size == nil || size == Float::INFINITY || size == -Float::INFINITY
76 return nil unless size.is_a?(Integer)
77 total_size *= size
78 end
79 total_size
80 end
81
82 def rewind
83 @__enums.each do |enum|
84 enum.rewind if enum.respond_to?(:rewind)
85 end
86 self
87 end
88
89 private def initialize_copy(other)
90 return self if self.equal?(other)
91
92 raise TypeError if !(Product === other)
93
94 super(other)
95
96 other_enums = other.instance_variable_get(:@__enums)
97
98 raise ArgumentError.new("uninitialized product") unless other_enums
99
100 @__enums = other_enums
101
102 self
103 end
104 end
105end
106