diff --git a/mrbgems/mruby-enum-chain/README.md b/mrbgems/mruby-enum-chain/README.md new file mode 100644 index 000000000..f2fd104da --- /dev/null +++ b/mrbgems/mruby-enum-chain/README.md @@ -0,0 +1,80 @@ +# mruby-enum-chain + +## Description + +This mrbgem provides the `Enumerator::Chain` class, which allows you to chain multiple enumerable objects together, treating them as a single, continuous enumerable. + +This is useful when you have multiple collections (e.g., arrays, ranges, or other enumerators) and you want to iterate over all of them sequentially without first concatenating them into a single, larger collection. + +## How to Use + +There are three main ways to create an `Enumerator::Chain` instance: + +### 1. Using `Enumerable#chain` + +You can call the `chain` method on any object that includes the `Enumerable` module. + +```ruby +a = [1, 2, 3] +b = (4..6) +c = {foo: 7, bar: 8}.each_key # Enumerator for keys + +chained_enum = a.chain(b, c) +chained_enum.to_a # => [1, 2, 3, 4, 5, 6, :foo, :bar] +``` + +### 2. Using `Enumerator#+` + +You can use the `+` operator on an `Enumerator` instance to chain it with another enumerable object. + +```ruby +enum1 = [1, 2].each +enum2 = %w(a b).each + +chained_enum = enum1 + enum2 +chained_enum.to_a # => [1, 2, "a", "b"] + +# You can chain multiple times +enum3 = (10..11).each +chained_enum_2 = enum1 + enum2 + enum3 +chained_enum_2.to_a # => [1, 2, "a", "b", 10, 11] +``` + +### 3. Using `Enumerator::Chain.new` + +You can directly instantiate `Enumerator::Chain` by passing enumerable objects to its constructor. + +```ruby +arr = [10, 20] +rng = (30..31) + +chained_enum = Enumerator::Chain.new(arr, rng) +chained_enum.to_a # => [10, 20, 30, 31] +``` + +## Key Features + +- **`each(&block)`**: Iterates through each element of the chained enumerables in the order they were added. Returns an enumerator if no block is given. +- **`size`**: Returns the total number of elements in all chained enumerables. If any of the chained enumerables do not respond to `size` (e.g., an infinite enumerator or one with an unknown size), this method will return `nil`. + + ```ruby + ([1, 2].chain([3, 4])).size # => 4 + ([1, 2].chain( (1..Float::INFINITY) )).size # => nil + ``` + +- **`rewind`**: Rewinds all of the chained enumerables that respond to the `rewind` method. This resets the iteration state to the beginning. + + ```ruby + e = [1,2].chain(3..4) + e.next # => 1 + e.next # => 2 + e.next # => 3 + e.rewind + e.next # => 1 + ``` + +- **`+(other)`**: Creates a new `Enumerator::Chain` by appending another enumerable to the current chain. + +## License + +MIT License