[#89806] [Ruby trunk Bug#15306] Generate prelude.c using miniruby — v.ondruch@...
Issue #15306 has been reported by vo.x (Vit Ondruch).
3 messages
2018/11/15
[ruby-core:89916] [Ruby trunk Feature#15144] Enumerator#chain
From:
knu@...
Date:
2018-11-21 06:26:52 UTC
List:
ruby-core #89916
Issue #15144 has been updated by knu (Akinori MUSHA).
File 0001-Implement-Enumerator-Chain-and-Enumerator-chain-Feat.patch added
I've written an initial implementation as attached:
- `Enumerator.chain(*enums)` to generate an enumerator chain of `enums`
- `Enumerator#+(other)` to generate an enumerator chain of `[self, other]`
- `Enumerator#chain(*others)` to generate an enumerator chain of `[self, *others]`
Some notes:
- The constructor is currently `Enumerator::Chain.new(*enums)` but it should probably be `Enumerator::Chain.new(enums)` to make it extensible to take an enumerable in general, with `itertools.chain.from_iterable` of Python in mind.
- `Enumerator.chain(Enumerator.chain(e1, e2), e3)` cannot be optimized to `Enumerator.chain(e1, e2, e3)` because it is expected that the intermediate object `Enumerator.chain(e1, e2)` is expected to receive a call for `each` when `Enumerator.chain(Enumerator.chain(e1, e2), e3).each {…}` is called.
----------------------------------------
Feature #15144: Enumerator#chain
https://bugs.ruby-lang.org/issues/15144#change-74999
* Author: zverok (Victor Shepelev)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version:
----------------------------------------
I am not sure I am not missing something, but...
```ruby
[1, 2, 3].each.chain([3, 4, 5].each) # => Enumerator
```
...seem to be a useful pattern.
It especially shows itself in case of lazy enumerators, representing several long-calculated sequences, like something...
```ruby
# just data from several sources, abstracted into enumerator, fetching it on demand
process = URLS.lazy.map(&Faraday.method(:get)))
.chain(LOCAL_FILES.lazy.map(&File.method(:read)))
.chain(FALLBACK_FILE.then.lazy.map(&File.method(:read))) # with yield_self aka then we can even chain ONE value
process.detect { |val| found?(val) } # uniformely search several sources (lazy-loading them) for some value
# tty-progressbar is able to work with enumerables:
bar = TTY::ProgressBar.new("[:bar]", total: URLS.count + LOCAL_FILES.count + 1)
bar.iterate(process).detect { |val| found?(val) } # shows progress-bar for uniform process of detection
```
Prototype impl. is dead simple, of course:
```ruby
class Enumerator
def chain(*others)
Enumerator.new { |y|
[self, *others].each { |e| e.each { |v| y << v } }
}
end
end
```
Obviously, the effect could be reached with `flat_map`, but it seems "chaining" of iterations is pretty common and clear concept (and Google search for "ruby enumerator chain" shows people constantly ask about the way).
---Files--------------------------------
0001-Implement-Enumerator-Chain-and-Enumerator-chain-Feat.patch (13.3 KB)
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>