mrbgems/mruby-enum-lazy/README.md
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.
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 / collectselect / find_allrejectgrepgrep_vdropdrop_whiletaketake_whileflat_map / collect_concatzipuniqTo trigger the evaluation of the lazy operations and retrieve all results (if finite), you can use methods like force or to_a.
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.
Here's a simple example demonstrating lazy evaluation:
# 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]
This gem depends on the following mruby core gems:
mruby-enumeratormruby-enum-extMIT License
mruby developers
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)