From: sin@... Date: 2020-05-25T23:33:48+00:00 Subject: [ruby-core:98512] [Ruby master Feature#16913] Add `ARGF#each_io` 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: