No commit activity in last 3 years
No release in over 3 years
This is just a showcase gem to support language core proposal.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

 Project Readme

Enumerator#generate

This is an alternative to Object#enumerate Ruby language core proposal. Goal is the same: generating enumerators which can idiomatically replace (most of) while and loop cycles.

After some experiments, it turns out that "start from initial value, and continue with this block" (like Object#enumerate does) is not the only important use case. "Just enumerate with this block" is equally important, and Enumerator#generate supports this case finely. Also, the call sequence seems to be less confusing, it is pretty straight: Enumerator#generate generates an enumerator from block and optional initial value.

Synopsys

Enumerator#generate takes a block and optional initial value, and generates (infinite) enumerator by applying the block to result of previous iteration. If initial value is not passed, first block receives no arguments.

Examples of usage

With initial value

# Infinite sequence
p Enumerator.generate(1, &:succ).take(5)
# => [1, 2, 3, 4, 5]

# Easy Fibonacci
p Enumerator.generate([0, 1]) { |f0, f1| [f1, f0 + f1] }.take(10).map(&:first)
#=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

require 'date'

# Find next Tuesday
p Enumerator.generate(Date.today, &:succ).detect { |d| d.wday == 2 }
# => #<Date: 2018-05-22 ((2458261j,0s,0n),+0s,2299161j)>

(Other examples from Object#enumerate are easily translated, too.)

Without initial value

# Random search
target = 7
p Enumerator.generate { rand(10) }.take_while { |i| i != target }.to_a
# => [0, 6, 3, 5,....]

# External while condition
require 'strscan'
scanner = StringScanner.new('7+38/6')
p Enumerator.generate { scanner.scan(%r{\d+|[-+*/]}) }.slice_after { scanner.eos? }.first
# => ["7", "+", "38", "/", "6"]

# Potential message loop system:
Enumerator.generate { Message.receive }.take_while { |msg| msg != :exit }