mrbgems/mruby-enumerator/README.md
The mruby-enumerator mrbgem provides the Enumerator class, which allows for both internal and external iteration in mruby.
Enumerators are useful when you want to work with collections of data in a flexible way. They allow you to:
next.You can create an Enumerator in several ways:
Using Kernel#to_enum or Kernel#enum_for: This is the most common way. You can turn any object that has an each method (or a similar iteration method) into an Enumerator.
e = [1, 2, 3].to_enum # Creates an enumerator for the array
e = "hello".enum_for(:each_byte) # Creates an enumerator for iterating over bytes
Using Enumerator.new: You can create an Enumerator by providing a block that defines how values are yielded.
fib = Enumerator.new do |yielder|
a = b = 1
loop do
yielder << a
a, b = b, a + b
end
end
fib.take(5) # => [1, 1, 2, 3, 5]
The Enumerator class includes many helpful methods from the Enumerable module, as well as some of its own:
next: Returns the next value from the enumerator. Raises StopIteration if the enumerator is at the end.
peek: Returns the next value without advancing the iterator.
rewind: Resets the enumerator to its beginning.
with_index(offset = 0): Iterates over elements, providing both the element and its index (with an optional offset). Returns a new Enumerator if no block is given.
["a", "b"].each.with_index(1) do |char, index|
puts "#{index}: #{char}"
end
# Output:
# 1: a
# 2: b
each_with_index: Similar to with_index(0).
with_object(obj): Iterates over elements, passing an arbitrary object along with each element. Returns the given object. Returns a new Enumerator if no block is given.
(1..3).each.with_object([]) do |i, arr|
arr << i * 2
end # => [2, 4, 6]
each(*args): Iterates over the enumerator. If arguments are provided, they are passed to the underlying iteration method.
feed(value): Sets a value to be returned by the yield inside the enumerator on its next call.
One of the powerful features of Enumerators is the ability to chain operations:
data = [1, 2, 3, 4, 5]
result = data.to_enum
.with_index # [[1, 0], [2, 1], [3, 2], [4, 3], [5, 4]]
.select { |num, idx| num.even? } # [[2, 1], [4, 3]]
.map { |num, idx| "#{idx}:#{num}" } # ["1:2", "3:4"]
p result # => ["1:2", "3:4"]
This avoids creating intermediate arrays for each step, making the code more efficient and readable for complex data transformations.
This mrbgem integrates the Enumerator class into mruby, making it available for use in your mruby projects. It also extends Kernel with to_enum and enum_for, and Enumerable with methods like zip, chunk, and chunk_while that leverage Enumerator.
Refer to the source code and tests for more detailed examples and advanced usage.