Skip to content

Commit f785366

Browse files
committed
Enhance documentation for Fast Forward Iterators
- Expanded the "Functional Patterns" section to clarify the use of closures and added examples for `ClosureIteratorIterator` and `ClosureFactoryIteratorAggregate`. - Updated the "Advanced Topics" index to include new sections and improve navigation. - Improved the "Factories & Utilities" documentation with detailed usage examples for `ClosureFactoryIteratorAggregate` and `debugIterable()`. - Introduced a new "Foundations and Extension Points" document outlining base classes for custom iterator development. - Revised the "API Reference" to better describe the public API surface and its components. - Enhanced the "Iterators" section with clearer descriptions and examples for various iterator classes. - Added a "Compatibility" section detailing version support and behavioral compatibility notes. - Created an "FAQ" section addressing common questions and usage scenarios. - Updated the "Getting Started" guide to provide clearer installation instructions and verification steps. - Expanded the "Quickstart" section with additional examples and explanations of iterator behavior. - Improved the "Usage Patterns" section to guide users in selecting the appropriate iterator for their needs. - Added comprehensive "Use Cases" to illustrate practical applications of iterators in real-world scenarios. - Included a new "Dependencies" section outlining runtime and development requirements. - Enhanced the "Links & Resources" section for better navigation and access to external references. Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
1 parent 1769fd9 commit f785366

24 files changed

Lines changed: 1258 additions & 212 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Enhance your PHP applications with high-performance iterators: lookahead, peekin
2222
Install via Composer:
2323

2424
```bash
25-
composer require php-fast-forward/iterators
25+
composer require fast-forward/iterators
2626
```
2727

2828
**Requirements:** PHP 8.3 or higher

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"ergebnis/composer-normalize": true,
4343
"fast-forward/dev-tools": true,
4444
"phpdocumentor/shim": true,
45-
"phpro/grumphp": true
45+
"phpro/grumphp": true,
46+
"pyrech/composer-changelogs": true
4647
},
4748
"platform": {
4849
"php": "8.3.0"
Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,66 @@
11
Caching & Rewinding
22
===================
33

4-
- ``GeneratorCachingIteratorAggregate``: Caches generator results for repeatable iteration.
5-
- ``GeneratorRewindableIterator``: Allows rewinding generators, making them reusable.
4+
Generators are naturally single-pass, which is perfect for streaming but
5+
problematic when your workflow needs a second iteration. This package offers
6+
three related tools for that situation.
67

7-
Example:
8+
Comparison guide
9+
----------------
10+
11+
.. list-table:: Choose the replay strategy that matches your API
12+
:header-rows: 1
13+
:widths: 28 30 42
14+
15+
* - Class
16+
- Best when...
17+
- Important note
18+
* - ``GeneratorCachingIteratorAggregate``
19+
- you want an aggregate that can be iterated repeatedly
20+
- cached values remain available after the first traversal
21+
* - ``GeneratorRewindableIterator``
22+
- you want a direct iterator that feels like a reusable generator
23+
- rewinding rebuilds the visible iterator from cached values
24+
* - ``RepeatableIteratorIterator``
25+
- you want a fixed number of repeated reads from a finite source
26+
- designed for controlled repetition, not for infinite processing loops
27+
28+
Example with repeated generator reads
29+
-------------------------------------
830

931
.. code-block:: php
1032
11-
$generator = function () {
12-
yield from [1,2,3];
13-
};
14-
$caching = new GeneratorCachingIteratorAggregate($generator());
15-
foreach ($caching as $val) {
16-
echo $val . "\n";
33+
use FastForward\Iterator\GeneratorRewindableIterator;
34+
35+
$generator = new GeneratorRewindableIterator((function (): Generator {
36+
yield from [1, 2, 3];
37+
})());
38+
39+
foreach ($generator as $value) {
40+
echo $value . PHP_EOL;
41+
}
42+
43+
foreach ($generator as $value) {
44+
echo $value . PHP_EOL;
1745
}
18-
// Can iterate again without loss.
1946
20-
**Expected output:**
47+
Expected output:
2148

2249
.. code-block:: text
2350
2451
1
2552
2
2653
3
54+
1
55+
2
56+
3
57+
58+
Memory trade-off
59+
----------------
60+
61+
Replayable iteration depends on caching. That means:
62+
63+
- it is a good fit for medium-sized or expensive-to-produce sequences;
64+
- it is a poor fit for very large unbounded streams;
65+
- you should document the buffering behavior clearly if you build your own
66+
generator wrappers on top of these classes.
Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,60 @@
11
Combining Iterators
2-
==================
2+
===================
3+
4+
This package ships three different "combine several sources" strategies. They
5+
look similar at a glance but solve different problems.
6+
7+
Comparison table
8+
----------------
9+
10+
.. list-table:: Chain vs interleave vs zip
11+
:header-rows: 1
12+
:widths: 24 32 44
13+
14+
* - Class
15+
- What it does
16+
- Best fit
17+
* - ``ChainIterableIterator``
18+
- consumes one source completely, then moves to the next
19+
- paginated APIs, fallback lists, sequential data merges
20+
* - ``InterleaveIteratorIterator``
21+
- alternates between active sources in round-robin order
22+
- fairness-oriented scheduling, balanced output from uneven sources
23+
* - ``ZipIteratorIterator``
24+
- reads all sources in lockstep and yields tuples
25+
- pairwise alignment, parallel datasets, side-by-side records
26+
27+
Concrete example
28+
----------------
329

4-
Combine multiple iterators in flexible ways using:
5-
6-
- ``ChainIterableIterator``: Chains multiple iterables into a single iterator.
7-
- ``InterleaveIteratorIterator``: Interleaves elements from several iterators.
8-
- ``ZipIteratorIterator``: Zips multiple iterators together, yielding tuples.
30+
.. code-block:: php
931
10-
Example:
32+
use FastForward\Iterator\ChainIterableIterator;
33+
use FastForward\Iterator\InterleaveIteratorIterator;
34+
use FastForward\Iterator\ZipIteratorIterator;
1135
12-
.. code-block:: php
36+
$letters = ['A', 'B', 'C'];
37+
$numbers = [1, 2];
1338
14-
$a = new ArrayIterator([1,2,3]);
15-
$b = new ArrayIterator([4,5,6]);
16-
$chain = new ChainIterableIterator([$a, $b]);
17-
foreach ($chain as $val) {
18-
echo $val . "\n";
19-
}
39+
echo json_encode(iterator_to_array(new ChainIterableIterator($letters, $numbers), false)) . PHP_EOL;
40+
echo json_encode(iterator_to_array(new InterleaveIteratorIterator($letters, $numbers), false)) . PHP_EOL;
41+
echo json_encode(iterator_to_array(new ZipIteratorIterator($letters, $numbers), false)) . PHP_EOL;
2042
21-
**Expected output:**
43+
Expected output:
2244

2345
.. code-block:: text
2446
25-
1
26-
2
27-
3
28-
4
29-
5
30-
6
47+
["A","B","C",1,2]
48+
["A",1,"B",2,"C"]
49+
[["A",1],["B",2]]
50+
51+
Common mistakes
52+
---------------
53+
54+
- If you expected ``ZipIteratorIterator`` to keep reading after the shortest
55+
input ends, you probably wanted ``ChainIterableIterator`` or
56+
``InterleaveIteratorIterator`` instead.
57+
- If you expected ``InterleaveIteratorIterator`` to preserve original numeric
58+
keys, note that numeric keys are normalized while string keys are preserved.
59+
- If you only need to append several iterables, ``ChainIterableIterator`` is the
60+
simplest and easiest to reason about.

docs/advanced/debugging.rst

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,46 @@
11
Debugging Iterables
2-
==================
2+
===================
33

4-
Use the utility function ``debugIterable()`` to print and inspect any traversable object during development.
4+
Use ``debugIterable()`` when you want a quick snapshot of what an iterator is
5+
currently exposing without writing custom dump code around every experiment.
56

6-
Example:
7+
Basic usage
8+
-----------
79

810
.. code-block:: php
911
10-
use function FastForward\Iterator\debugIterable;
12+
use function FastForward\Iterator\debugIterable;
1113
12-
$it = new ArrayIterator([1,2,3]);
13-
debugIterable($it, 'Section Title');
14+
$it = new ArrayIterator([1, 2, 3]);
15+
debugIterable($it, 'Section Title');
1416
15-
**Expected output:**
17+
Expected output:
1618

1719
.. code-block:: text
1820
19-
=== Section Title ===
21+
=== Section Title ===
2022
21-
Length: 3
22-
Output: [
23-
0 => "1",
24-
1 => "2",
25-
2 => "3",
26-
]
23+
Length: 3
24+
Output: [
25+
0 => 1,
26+
1 => 2,
27+
2 => 3,
28+
]
2729
28-
This prints each key-value pair, helping you understand the state of your iterators.
30+
When it is especially useful
31+
----------------------------
32+
33+
- after composing several iterators and losing track of the final output shape;
34+
- while comparing ``ChainIterableIterator``, ``InterleaveIteratorIterator``, and
35+
``ZipIteratorIterator``;
36+
- while checking how grouping iterators structure their arrays;
37+
- while verifying whether keys were preserved or normalized.
38+
39+
Tips
40+
----
41+
42+
- Pass a section title so multiple debug blocks are easy to scan in one script.
43+
- Debug early in the pipeline and again at the end if you are composing several
44+
wrappers.
45+
- Remember that ``debugIterable()`` calls ``count()``. That is useful, but it
46+
also means the underlying iterator should support safe counting.

docs/advanced/examples.rst

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,62 @@
11
Examples
22
========
33

4-
Explore real-world usage in the `examples/` directory. Each file demonstrates a specific iterator or pattern:
4+
The ``examples/`` directory is one of the fastest ways to understand the
5+
library. Each script is small, focused, and easy to run in isolation.
56

6-
- `chain-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/chain-iterator.php>`_
7-
- `chunked-iterator-aggregate.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/chunked-iterator-aggregate.php>`_
8-
- `closure-factory-iterator-aggregate.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/closure-factory-iterator-aggregate.php>`_
9-
- `closure-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/closure-iterator-iterator.php>`_
10-
- `consecutive-group-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/consecutive-group-iterator.php>`_
11-
- `file-extension-filter-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/file-extension-filter-iterator.php>`_
12-
- `generator-caching-iterator-aggregate.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/generator-caching-iterator-aggregate.php>`_
13-
- `generator-rewindable-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/generator-rewindable-iterator.php>`_
14-
- `group-by-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/group-by-iterator-iterator.php>`_
15-
- `interleave-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/interleave-iterator-iterator.php>`_
16-
- `lookahead-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/lookahead-iterator.php>`_
17-
- `range-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/range-iterator.php>`_
18-
- `repeatable-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/repeatable-iterator-iterator.php>`_
19-
- `sliding-window-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/sliding-window-iterator-iterator.php>`_
20-
- `trim-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/trim-iterator-iterator.php>`_
21-
- `unique-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/unique-iterator-iterator.php>`_
22-
- `zip-iterator-iterator.php`: `View on GitHub <https://github.com/php-fast-forward/iterators/blob/main/examples/zip-iterator-iterator.php>`_
7+
Suggested reading map
8+
---------------------
239

24-
Browse these files for hands-on demonstrations of each feature and pattern.
10+
.. list-table:: What each example teaches
11+
:header-rows: 1
12+
:widths: 38 62
13+
14+
* - Example file
15+
- What to look for
16+
* - `chain-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/chain-iterator.php>`_
17+
- sequential combination of multiple iterables
18+
* - `chunked-iterator-aggregate.php <https://github.com/php-fast-forward/iterators/blob/main/examples/chunked-iterator-aggregate.php>`_
19+
- fixed-size batching with different chunk sizes
20+
* - `closure-factory-iterator-aggregate.php <https://github.com/php-fast-forward/iterators/blob/main/examples/closure-factory-iterator-aggregate.php>`_
21+
- factory-based lazy iterable creation
22+
* - `closure-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/closure-iterator-iterator.php>`_
23+
- value transformation with closures
24+
* - `consecutive-group-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/consecutive-group-iterator.php>`_
25+
- grouping adjacent runs
26+
* - `file-extension-filter-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/file-extension-filter-iterator.php>`_
27+
- filtering filesystem entries by extension
28+
* - `generator-caching-iterator-aggregate.php <https://github.com/php-fast-forward/iterators/blob/main/examples/generator-caching-iterator-aggregate.php>`_
29+
- replaying generator-backed aggregates
30+
* - `generator-rewindable-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/generator-rewindable-iterator.php>`_
31+
- rewinding generator output and repeating it
32+
* - `group-by-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/group-by-iterator-iterator.php>`_
33+
- full-dataset grouping by computed keys
34+
* - `interleave-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/interleave-iterator-iterator.php>`_
35+
- round-robin traversal and mixed key behavior
36+
* - `lookahead-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/lookahead-iterator.php>`_
37+
- peeking ahead and behind without consuming values
38+
* - `range-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/range-iterator.php>`_
39+
- integer, float, and boundary-aware ranges
40+
* - `repeatable-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/repeatable-iterator-iterator.php>`_
41+
- controlled repetition with limits and offsets
42+
* - `sliding-window-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/sliding-window-iterator-iterator.php>`_
43+
- overlapping windows of different sizes
44+
* - `trim-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/trim-iterator-iterator.php>`_
45+
- whitespace trimming and custom character masks
46+
* - `unique-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/unique-iterator-iterator.php>`_
47+
- strict and non-strict deduplication
48+
* - `zip-iterator-iterator.php <https://github.com/php-fast-forward/iterators/blob/main/examples/zip-iterator-iterator.php>`_
49+
- lockstep combination of several iterables
50+
51+
Recommended order
52+
-----------------
53+
54+
If you are new to the package, a friendly order is:
55+
56+
1. ``chunked-iterator-aggregate.php``
57+
2. ``sliding-window-iterator-iterator.php``
58+
3. ``closure-iterator-iterator.php``
59+
4. ``unique-iterator-iterator.php``
60+
5. ``chain-iterator.php``
61+
6. ``interleave-iterator-iterator.php``
62+
7. ``zip-iterator-iterator.php``

docs/advanced/extending.rst

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
Extending the Library
2+
=====================
3+
4+
Fast Forward Iterators does not require a container, a framework integration, or
5+
package-specific service registration. Extension is intentionally simple: build
6+
on top of the public iterator base classes and pass around ordinary PHP
7+
iterables.
8+
9+
Recommended extension workflow
10+
------------------------------
11+
12+
1. accept ``iterable`` as input whenever possible;
13+
2. normalize it with ``IterableIterator`` if you need a consistent ``Iterator``;
14+
3. choose the smallest countable base class that matches your design;
15+
4. keep the output shape obvious in both naming and documentation.
16+
17+
Choosing the right base class
18+
-----------------------------
19+
20+
.. list-table:: Extension guide
21+
:header-rows: 1
22+
:widths: 26 34 40
23+
24+
* - Base class
25+
- Best for
26+
- Example ideas
27+
* - ``CountableIteratorAggregate``
28+
- generator-based or delegated iteration
29+
- chunking, mapping, flattening, lazy adapters
30+
* - ``CountableIteratorIterator``
31+
- wrappers around an existing iterator
32+
- transforming values, remapping keys, peeking helpers
33+
* - ``CountableFilterIterator``
34+
- boolean acceptance rules
35+
- path filters, record filters, validation gates
36+
* - ``CountableIterator``
37+
- full stateful control
38+
- custom navigation, multi-source coordination, specialized range logic
39+
40+
Practical advice
41+
----------------
42+
43+
- Prefer aggregates when you can express the behavior with ``yield``.
44+
- Prefer wrappers when you want to preserve most behavior of an inner iterator.
45+
- Document whether your iterator preserves original keys or emits normalized
46+
sequential keys.
47+
- Call out whether a class buffers values in memory. This matters for
48+
``LookaheadIterator``, grouping iterators, and generator replay strategies.
49+
50+
No hidden framework hooks
51+
-------------------------
52+
53+
This package does not expose:
54+
55+
- aliases;
56+
- singletons;
57+
- framework-specific service providers;
58+
- PSR-11 container bindings.
59+
60+
That keeps custom integration straightforward: instantiate the iterator directly
61+
where you need it, or register it in your own application container using normal
62+
PHP construction rules.

0 commit comments

Comments
 (0)