[ruby-core:98512] [Ruby master Feature#16913] Add `ARGF#each_io`
From:
sin@...
Date:
2020-05-25 23:33:48 UTC
List:
ruby-core #98512
Issue #16913 has been reported by prajjwal (Prajjwal Singh).
----------------------------------------
Feature #16913: Add `ARGF#each_io`
https://bugs.ruby-lang.org/issues/16913
* Author: prajjwal (Prajjwal Singh)
* Status: Open
* Priority: Normal
----------------------------------------
Add an iterator for each file supplied on the command line, or STDIN. `ARGF#each_io`
## Current Status
Often, we need to do something with individual files ARGF knows about rather than the concatenation of them. We can combine `ARGF#to_io` and `ARGF#skip` to achieve this as follows:
```ruby
while (file = ARGF.to_io)
break if file.closed? || file.eof?
csv = CSV.new(file)
csv.each { |line| p line }
ARGF.skip
end
```
## Proposal
Add an iterator `ARGF#each_io` to do the above. The above example would then become:
```ruby
ARGF.each_io do |io|
csv = CSV.new(io)
csv.each { |line| p line }
end
```
The name is `#each_io`. We could call it `#each_file` as well, but `ARGF#to_io` emits an `IO` object when the current file is `STDIN`.
## Implementation
A cursory ruby implementation is below. Could better handle the `STDIN` edge case, and would probably be better off being written in C.
```ruby
def ARGF.each_io(&fn)
raise 'ARGF#each_io needs a block!' unless block_given?
while (file = to_io)
break if file.closed? || file.eof?
fn.call(file)
# File was STDIN, no need to go any further.
break if file.class == IO
skip
end
end
```
## Issues
* Handling the `STDIN` edge case is ugly.
* Not clear if `eof?` checking for `STDIN` should be left up to the user instead.
* A real world implementation should return a proper iterator instead of the above.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>