From: "georgeclaghorn (George Claghorn)" Date: 2021-11-22T21:03:39+00:00 Subject: [ruby-core:106215] [Ruby master Feature#18357] Proposal: stop raising when block passed to IO#each_* closes the IO Issue #18357 has been reported by georgeclaghorn (George Claghorn). ---------------------------------------- Feature #18357: Proposal: stop raising when block passed to IO#each_* closes the IO https://bugs.ruby-lang.org/issues/18357 * Author: georgeclaghorn (George Claghorn) * Status: Open * Priority: Normal ---------------------------------------- As of #17661, all of the enumeration methods on `IO`���e.g. `each_line`, `each_byte`, `each_codepoint`���raise `IOError` when the given block closes the `IO`. For example, the following code raises an `IOError` if the peer sends a line containing only `quit`: ``` ruby socket.each_line do |line| if line.casecmp?("quit\n") socket.puts "Goodbye" socket.close end end ``` In this example, it���s trivial to `break` after closing the client socket. However, in real code, it���s likely that the command-handling code will be further away from the loop and unable to `break` out of the loop. Either the command-handling method and all intervening methods need to pass an indication of whether to keep reading back down the stack, or the block needs to include an explicit `break if io.closed?`. In my experience, when I close an `IO`within a read loop, I intend to immediately stop reading as well. It would be more agreeable if `each_line` et al. simply stopped reading when the `IO` is closed in the block instead of raising `IOError`. I recognize this may be considered a breaking change. The patch for #17661 was backported to 3.0, and `each_line` has behaved this way for longer. This may be workable as an option to the enumeration methods, but I���m not sure an option is worth its weight compared to explicit `break if io.closed?`. I���m mostly asking for a decision on whether the implicit behavior is worth changing for convenience and developer happiness (and aware the answer may be no). I���ve attached a patch containing a sample implementation for `IO#each_line` and updated specs. I believe this change can be implemented similarly for all other enumeration methods. ---Files-------------------------------- patch.diff (1.66 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: