calog/vendor/mruby/mrbgems/mruby-enum-lazy/README.md
2026-07-04 20:25:00 -05:00

91 lines
2.6 KiB
Markdown
Vendored

# mruby-enum-lazy
## Overview
This mrbgem provides lazy evaluation for Enumerable objects in mruby. It introduces the `Enumerable#lazy` method, which returns an instance of `Enumerator::Lazy`. This allows for more efficient processing of collections, especially large or potentially infinite sequences, by evaluating elements only when they are needed.
## Functionality
When you call `.lazy` on an Enumerable object (like an Array or Range), you get back an `Enumerator::Lazy` object. This object behaves much like a regular Enumerator, but with a key difference: methods that transform the collection are deferred until the results are actually required.
The following methods are implemented to act lazily:
- `map` / `collect`
- `select` / `find_all`
- `reject`
- `grep`
- `grep_v`
- `drop`
- `drop_while`
- `take`
- `take_while`
- `flat_map` / `collect_concat`
- `zip`
- `uniq`
To trigger the evaluation of the lazy operations and retrieve all results (if finite), you can use methods like `force` or `to_a`.
### How it works
Operations on an `Enumerator::Lazy` object are chained together. The actual computation of each element is postponed until it's requested (e.g., by `force`, `to_a`, or iterating with `each`). This can lead to significant performance improvements by avoiding unnecessary computations and memory allocations, particularly when dealing with large data sets or when only a subset of results is needed.
## Usage Example
Here's a simple example demonstrating lazy evaluation:
```ruby
# Without lazy evaluation
# This would attempt to create an infinite array, which is not feasible.
# (1..Float::INFINITY).map { |x| x * x }.select { |x| x % 2 == 0 }.take(5).to_a
# With lazy evaluation
p (1..Float::INFINITY).lazy.map { |x| x * x }.select { |x| x % 2 == 0 }.take(5).force
# Output: [4, 16, 36, 64, 100]
# Another example:
a = [1, 2, 3, 4, 5]
lazy_sequence = a.lazy.map do |x|
puts "mapping #{x}"
x * 10
end.select do |x|
puts "selecting #{x}"
x > 20
end
puts "Applying force..."
result = lazy_sequence.force
# Output:
# mapping 1
# selecting 10
# mapping 2
# selecting 20
# mapping 3
# selecting 30
# mapping 4
# selecting 40
# mapping 5
# selecting 50
# Applying force...
p result # Output: [30, 40, 50]
```
## Dependencies
This gem depends on the following mruby core gems:
- `mruby-enumerator`
- `mruby-enum-ext`
## License
MIT License
## Author
mruby developers
## Acknowledgements
Based on <https://github.com/yhara/enumerable-lazy>
Inspired by <https://github.com/antimon2/enumerable_lz>
Reference: <http://jp.rubyist.net/magazine/?0034-Enumerable_lz> (ja)