https://github.com/zverok/enumerator_generate
Enumerator#generate Ruby core proposal demo
https://github.com/zverok/enumerator_generate
Last synced: 9 months ago
JSON representation
Enumerator#generate Ruby core proposal demo
- Host: GitHub
- URL: https://github.com/zverok/enumerator_generate
- Owner: zverok
- Created: 2018-05-21T18:07:55.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-06-06T09:07:30.000Z (about 8 years ago)
- Last Synced: 2024-04-24T08:26:15.969Z (about 2 years ago)
- Language: Ruby
- Size: 10.7 KB
- Stars: 4
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# `Enumerator#generate`
This is an alternative to [`Object#enumerate`](https://github.com/zverok/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
```ruby
# 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 }
# => #
```
(Other examples from [`Object#enumerate`](https://github.com/zverok/object_enumerate) are easily translated, too.)
### Without initial value
```ruby
# 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 }
```