From: "zverok (Victor Shepelev) via ruby-core" Date: 2024-08-03T17:31:47+00:00 Subject: [ruby-core:118785] [Ruby master Feature#20664] Add `before` and `until` options to Enumerator.produce Issue #20664 has been updated by zverok (Victor Shepelev). I am not sure about this API. I think in language core there aren���t many APIs that accept just a symbol of a necessary method (only `reduce(:+)` comes to mind, and I am still not sure why this form exists, because it seems to have been introduced at the same time when `Symbol#to_proc` was, so `reduce(:+)` and `reduce(&:+)` were always co-existing). Mostly callables are passed as a block (and therefore there can be only one); but some APIs accept another callable (any object with `#call` method, like Enumerator.new). So, what if condition is _not_ an method of the sequence?.. Should we accept callables, too? Or, what if the method���s user expects it to be a particular value (like `until: 0`), or a pattern (like `before: 0..1`). The alternative is ```ruby Enumerator.produce(File, &:superclass).take_until(&:nil?) ``` ...which is more or less the same character-count-wise, more powerful (any block can be used), and more atomic. The one problem we don���t currently have neither `Enumerable#take_until`, nor `Object#not_nil?`, to write something like ```ruby # this wouldn���t work Enumerator.produce(File, &:superclass).take_while(&:not_nil?) # though one can use Enumerator.produce(File, &:superclass).take_while(&:itself) #=> [File, IO, Object, BasicObject] ``` ...but in general, I suspect adding `Enumerable#take_until` to handle such cases ([and `#take_while_after`](https://bugs.ruby-lang.org/issues/18136) while we are on it :)) might be more powerful addition to the language, useful in many situations. ---------------------------------------- Feature #20664: Add `before` and `until` options to Enumerator.produce https://bugs.ruby-lang.org/issues/20664#change-109340 * Author: knu (Akinori MUSHA) * Status: Open ---------------------------------------- Enumerator.produce provides a nice way to generate an infinite sequence but is a bit awkward to define how to end a sequence. It lacks a simple and easy way to produce typical finite sequences in an intuitive syntax. This proposal attempts to solve the problem by adding these two options to the method: - `before`: when provided, it is used as a predicate to determine if an iteration should end before a generated value gets yielded. - `until`: when provided, it is used as a predicate to determine if an iteration should end until after a generated value gets yielded. Any value that responds to `to_proc` and returns a `Proc` object is accepted in these options. A typical use case for the `before` option is traversing a tree structure to iterate over the ancestors or following/preceding siblings of a node. The `until` option can be used when there is a clear definition of the "last" value to yield. ```ruby enum = Enumerator.produce(File, before: :nil?, &:superclass) enum.to_a #=> [File, IO, Object, BasicObject] enum = Enumerator.produce(3, until: :zero?, &:pred) enum_to_a #=> [3, 2, 1, 0] ``` ---Files-------------------------------- 0001-Add-before-and-until-options-to-Enumerator.produce.patch (10.7 KB) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/