Project

General

Profile

Feature #2631

Allow IO#reopen to take a block

Added by djberg96 (Daniel Berger) over 7 years ago. Updated 3 months ago.

Status:
Assigned
Priority:
Normal
Target version:
[ruby-core:27701]

Description

=begin
Please allow IO#reopen to accept a block. This would allow users to temporarily redirect output without having to manually reset the file descriptor. For example:

require 'mkmf'

# stdout redirected within block only
$stdout.reopen('/dev/null') do
if have_header('foo.h')
# Do stuff
end
end

# stdout now back to its former setting

I believe this is both convenient and intuitive when one considers the IO.open also takes a block.

Regards,

Dan
=end

Associated revisions

Revision 59142
Added by glass 3 months ago

Allow IO#reopen to take a block

  • io.c (rb_io_reopen): take a block and ensure the IO closed
    [Feature #2631]

  • test/ruby/test_io.rb: add a test

  • NEWS: add an entry for this change

History

#1 Updated by hongli (Hongli Lai) over 7 years ago

=begin
I don't think this can be implemented easily. This can be implemented if the IO object in question is a File for which you know the filename. For sockets, pipes and other stuff it becomes tricker: one can emulate it backing up the underlying file descriptor by dup()ing it, but in my opinion that goes against my expectation of what #reopen should do: to replace the file descriptor with something else.
=end

#2 Updated by matz (Yukihiro Matsumoto) over 7 years ago

=begin
Hi,

In message "Re: [Feature #2631] Allow IO#reopen to take a block"
on Sat, 23 Jan 2010 01:30:53 +0900, Hongli Lai redmine@ruby-lang.org writes:

|I don't think this can be implemented easily. This can be implemented if the IO object in question is a File for which you know the filename. For sockets, pipes and other stuff it becomes tricker: one can emulate it backing up the underlying file descriptor by dup()ing it, but in my opinion that goes against my expectation of what #reopen should do: to replace the file descriptor with something else.

Agreed. Besides that behavior would not be thread safe.

                        matz.

=end

#3 Updated by shyouhei (Shyouhei Urabe) over 7 years ago

=begin
+1, The idea of temporary intercepting any output to another IO is worth considering. Though I doubt to name that feature a "reopen".

So my suggestion is: create a new method, that takes a block, to intercept an IO.
=end

#4 Updated by djberg96 (Daniel Berger) over 7 years ago

=begin
On Fri, Jan 22, 2010 at 10:56 PM, Shyouhei Urabe redmine@ruby-lang.org wrote:

Issue #2631 has been updated by Shyouhei Urabe.

+1, The idea of temporary intercepting any output to another IO is worth considering.  Though I doubt to name that feature a "reopen".

How about IO#redirect.

=end

#5 Updated by znz (Kazuhiro NISHIYAMA) over 7 years ago

  • Category set to core
  • Target version set to 2.0.0

=begin

=end

#6 [ruby-core:43390] Updated by nahi (Hiroshi Nakamura) over 5 years ago

  • Description updated (diff)
  • Assignee set to shyouhei (Shyouhei Urabe)

Method name?

#7 [ruby-core:43394] Updated by akr (Akira Tanaka) over 5 years ago

I don't feel changing IO#reopen is great way to solve this issue.

How about spawn()?

Since Ruby 1.9, spawn provides a primitive for redirection.
It is thread safe.

Apart from that, I think $stdin, $stdout, $stderr can be thread-local
variables, though.

#8 Updated by shyouhei (Shyouhei Urabe) over 5 years ago

  • Status changed from Open to Assigned

#9 [ruby-core:48343] Updated by shyouhei (Shyouhei Urabe) almost 5 years ago

  • Target version changed from 2.0.0 to next minor

I was poked by _ko1. But we lack a implementation proposal.

So I move its target to next minor. It might happen to be implemented some time later but not today.

Any opinions?

#10 Updated by Anonymous 3 months ago

  • Status changed from Assigned to Closed

Applied in changeset trunk|r59142.


Allow IO#reopen to take a block

  • io.c (rb_io_reopen): take a block and ensure the IO closed
    [Feature #2631]

  • test/ruby/test_io.rb: add a test

  • NEWS: add an entry for this change

#11 [ruby-core:81740] Updated by naruse (Yui NARUSE) 3 months ago

  • Status changed from Closed to Open

匿名ユーザー wrote:

Applied in changeset trunk|r59142.


Allow IO#reopen to take a block

  • io.c (rb_io_reopen): take a block and ensure the IO closed
    [Feature #2631]

  • test/ruby/test_io.rb: add a test

  • NEWS: add an entry for this change

This patch looks doesn't recover the original $stdout.

Morever though this was approved before, this is strange because block changes global state.
If this is introduced in 7 years ago, it may be acceptable.
But in this 201x year Ruby really should support multithread unsafe code?
People who want to write unsafe code should explicitly write code like following.

require 'mkmf'

# stdout redirected within block only
orig_stdout = $stdout
open(IO:NULL, 'w') do |f|
  $stdout = f
  if have_header('foo.h')
    # Do stuff
  end
ensure
  $stdout = orig_stdout
end

#12 Updated by naruse (Yui NARUSE) 3 months ago

  • Target version changed from next minor to 2.5

#13 [ruby-core:81744] Updated by Glass_saga (Masaki Matsushita) 3 months ago

  • Assignee changed from shyouhei (Shyouhei Urabe) to Glass_saga (Masaki Matsushita)
  • Status changed from Open to Closed

#14 Updated by Glass_saga (Masaki Matsushita) 3 months ago

  • Status changed from Closed to Assigned

#15 [ruby-core:81745] Updated by Glass_saga (Masaki Matsushita) 3 months ago

It was thoughtless. Let me revert it.

Also available in: Atom PDF