[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

closing stderr

mgarriss

9/18/2003 3:50:00 PM

I would like to prevent some output that is going to stderr during a
call to a third party lib just during that call. My first guess was:

STDERR.close_write
ThirdPartyLib::call_some_annoying_function
STDERR.????

I guess you can see my problem. Can anyone give me a lead on this?

TIA,
Michael


14 Answers

Robert Klemme

9/18/2003 4:13:00 PM

0


"Michael Garriss" <mgarriss@earthlink.net> schrieb im Newsbeitrag
news:3F69D414.70008@earthlink.net...
> I would like to prevent some output that is going to stderr during a
> call to a third party lib just during that call. My first guess was:
>
> STDERR.close_write
> ThirdPartyLib::call_some_annoying_function
> STDERR.????
>
> I guess you can see my problem. Can anyone give me a lead on this?
>
> TIA,
> Michael
>
>

require ''StringIO''

oldStdErr = $stderr
oldSTDERR = STDERR

$stderr = StringIO.new
STDERR = $stderr

begin
# lib call
ensure
$stderr = oldStdErr
STDERR = oldSTDERR
end

robert

Alan Davies

9/18/2003 4:29:00 PM

0

Robert Klemme wrote:

> "Michael Garriss" <mgarriss@earthlink.net> schrieb im Newsbeitrag
> news:3F69D414.70008@earthlink.net...
>
>>I would like to prevent some output that is going to stderr during a
>>call to a third party lib just during that call. My first guess was:
>>
>>STDERR.close_write
>>ThirdPartyLib::call_some_annoying_function
>>STDERR.????
>>
>>I guess you can see my problem. Can anyone give me a lead on this?
>>
>>TIA,
>>Michael
>>
>>
>
>
> require ''StringIO''
>
> oldStdErr = $stderr
> oldSTDERR = STDERR
>
> $stderr = StringIO.new
> STDERR = $stderr
>
> begin
> # lib call
> ensure
> $stderr = oldStdErr
> STDERR = oldSTDERR
> end
>
> robert
>

I did it like this on windows recently:

oldStderr = $stderr.dup
$stderr.reopen("NUL", ''w'')

<do stuff>

$stderr.reopen(oldStderr)

Not sure if NUL works on linix/unix

Mark J. Reed

9/18/2003 4:30:00 PM

0

On Fri, Sep 19, 2003 at 12:49:43AM +0900, Michael Garriss wrote:
> I would like to prevent some output that is going to stderr during a
> call to a third party lib just during that call. My first guess was:
>
> STDERR.close_write
> ThirdPartyLib::call_some_annoying_function
> STDERR.????

If the third-party library is a Ruby library and is well-behaved,
then you don''t have to mess with STDERR; just change $stderr to
point to someplace else.

Remember: the global variable $stderr is where Ruby actually sends
standard error output. The constant STDERR is just a saved
copy of the value $stderr got when Ruby started up.

So something like this should do the trick:

begin
$stderr = File.open(''/dev/null'', ''w'')
ThirdPartyLib::call_some_annoying_function
ensure
$stderr = STDERR
end

If, on the other hand, the third-party library is not so well-behavied
and messes with STDERR directly, then you can close it. But you need to save
a copy of it first and restore it later.

begin
errCopy = ($stderr = STDERR).dup
STDERR.close
ThirdPartyLib::call_some_annoying_function
ensure
$stderr = errCopy
STDERR = $stderr
end

Note that you have to assign something open to $stderr before assigning
to STDERR, or else the assignment to STDERR throws an exception trying to
print the "already initialized constant" warning and the assignment
doesn''t complete. There is probably a cleaner way of doing this.

Question on the subject of well-behaved libraries: if you invoke
native code from Ruby, is that run with file descriptor 2 initially
matching $stderr?

-Mark

Rudolf Polzer

9/18/2003 4:32:00 PM

0

Scripsit illa aut ille &#187;Robert Klemme&#171; <bob.news@gmx.net>:
> "Michael Garriss" <mgarriss@earthlink.net> schrieb im Newsbeitrag news:3F69D414.70008@earthlink.net...
> > I would like to prevent some output that is going to stderr during a
> > call to a third party lib just during that call. My first guess was:
> >
> > STDERR.close_write
> > ThirdPartyLib::call_some_annoying_function
> > STDERR.????
> >
> > I guess you can see my problem. Can anyone give me a lead on this?
[...]
> $stderr = StringIO.new
> STDERR = $stderr

Are you sure it occupies file descriptor 2 (which external libraries
normally use)?

def without_stderr(&block)
save = $stderr.dup()
$stderr.close() # this will affect STDERR, too.
begin
yield
ensure
$stderr = save.dup()
# SIDE EFFECT: the file descriptor STDERR points to will be valid again
end
end

However, this routine assumes that all file descriptors before
$stderr are used. This is the case unless $stdin or $stdout have
been closed. Is there something like dup2() in Ruby?


--
The only thing that Babelfish is good at is proving that Vogons are
great poets.
Josef ''Jupp'' Schugt in japan.anime.evangelion

Mark J. Reed

9/18/2003 4:36:00 PM

0

On Thu, Sep 18, 2003 at 05:28:31PM +0100, Alan Davies wrote:
> Not sure if NUL works on linix/unix

Definitely not. It will just create a file in the current directory
named "NUL". :)

There are no magic filenames on *N?X. There are, however, special
files which refer to hardware devices rather than disk storage. These
can be named anything, since it''s not the name that matters but
the file attributes, but there is a standard set of such files
in /dev on all systems. One of these is /dev/null, which points
to the "null device", which is not a real piece of hardware but a
virtual device that just discards everything written to it.
Another popular virtual device is /dev/zero, which will happily output
zero bytes as long as you care to continue reading from it.

In any case, we came up with much the same solution, differing only
in the filenames for the null device. The StringIO solution
seems like a better choice for cross-platform compatibility, however.

-Mark

mgarriss

9/18/2003 5:19:00 PM

0

Mark J. Reed wrote:

> <snip>

>Note that you have to assign something open to $stderr before assigning
>to STDERR, or else the assignment to STDERR throws an exception trying to
>print the "already initialized constant" warning and the assignment
>doesn''t complete. There is probably a cleaner way of doing this.
>
>
>

Thanks to all who responded!

Assign something open? I don''t understand. I get a syntax error on
that assignment:

bin/ruglyctl:132:in `require'':
/usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
(SyntaxError)
STDERR = $stderr
^ from bin/ruglyctl:132:in `handle_db_cmdtype''
from bin/ruglyctl:146

Regards,
Michael





Mark J. Reed

9/18/2003 6:00:00 PM

0

On Fri, Sep 19, 2003 at 02:18:35AM +0900, Michael Garriss wrote:
> Mark J. Reed wrote:
> >Note that you have to assign something open to $stderr before assigning
> >to STDERR, or else the assignment to STDERR throws an exception trying to
> >print the "already initialized constant" warning and the assignment
> >doesn''t complete. There is probably a cleaner way of doing this.
>
> Assign something open? I don''t understand. I get a syntax error on
> that assignment:

What I mean is that this assignment:

STDERR = blah

Generates a warning:

warning: already initialized constant STDERR

And that warning message is sent to - where else - $stderr.
Which means if $stderr is still pointing to a closed File object
at the time you try to assign to STDERR, Ruby tries to send the
warning about the assignment, fails to do so because $stderr is
closed, and aborts the assignment.

(It seems odd that failure to emit a warning would itself be fatal
to the surrounding operation, but that''s the behavior I''m seeing
on final 1.8.0)

> bin/ruglyctl:132:in `require'':
> /usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
> (SyntaxError)
> STDERR = $stderr

Hm, I''m not sure what that means. Is this running in mod_ruby?

-Mark

mgarriss

9/18/2003 6:40:00 PM

0

Mark J. Reed wrote:

>On Fri, Sep 19, 2003 at 02:18:35AM +0900, Michael Garriss wrote:
>
>
>>Mark J. Reed wrote:
>>
>>
>>>Note that you have to assign something open to $stderr before assigning
>>>to STDERR, or else the assignment to STDERR throws an exception trying to
>>>print the "already initialized constant" warning and the assignment
>>>doesn''t complete. There is probably a cleaner way of doing this.
>>>
>>>
>>Assign something open? I don''t understand. I get a syntax error on
>>that assignment:
>>
>>
>
>What I mean is that this assignment:
>
> STDERR = blah
>
>Generates a warning:
>
> warning: already initialized constant STDERR
>
>And that warning message is sent to - where else - $stderr.
>Which means if $stderr is still pointing to a closed File object
>at the time you try to assign to STDERR, Ruby tries to send the
>warning about the assignment, fails to do so because $stderr is
>closed, and aborts the assignment.
>
>(It seems odd that failure to emit a warning would itself be fatal
>to the surrounding operation, but that''s the behavior I''m seeing
>on final 1.8.0)
>
>
>
>>bin/ruglyctl:132:in `require'':
>>/usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
>>(SyntaxError)
>> STDERR = $stderr
>>
>>
>
>Hm, I''m not sure what that means. Is this running in mod_ruby?
>
>

No, not running this code in mod_ruby. It seems that the problem is
that it''s run from within a method. I guess I''m going to have to figure
out a way around that.

Michael


Mark J. Reed

9/18/2003 6:58:00 PM

0

On Fri, Sep 19, 2003 at 03:40:04AM +0900, Michael Garriss wrote:
> >>bin/ruglyctl:132:in `require'':
> >>/usr/www/apache/rugly/lib/rdb_rugly.rb:40: dynamic constant assignment
> >>(SyntaxError)
> >>STDERR = $stderr
> >>
>
> No, not running this code in mod_ruby. It seems that the problem is
> that it''s run from within a method.

Oh, right. You can fix that with eval.

eval "STDERR = $stderr"

But this is getting uglier all the time. Are you sure the
$stderr reassignment doesn''t work for you?

-Mark

Robert Klemme

9/19/2003 8:12:00 AM

0


"Rudolf Polzer" <denshimeiru-sapmctacher@durchnull.de> schrieb im
Newsbeitrag
news:slrnbmjng5.kqp.denshimeiru-sapmctacher@message-id.durchnull.ath.cx...
> Scripsit illa aut ille &#187;Robert Klemme&#171; <bob.news@gmx.net>:
> > "Michael Garriss" <mgarriss@earthlink.net> schrieb im Newsbeitrag
news:3F69D414.70008@earthlink.net...
> > > I would like to prevent some output that is going to stderr during a
> > > call to a third party lib just during that call. My first guess
was:
> > >
> > > STDERR.close_write
> > > ThirdPartyLib::call_some_annoying_function
> > > STDERR.????
> > >
> > > I guess you can see my problem. Can anyone give me a lead on this?
> [...]
> > $stderr = StringIO.new
> > STDERR = $stderr
>
> Are you sure it occupies file descriptor 2 (which external libraries
> normally use)?
>
> def without_stderr(&block)
> save = $stderr.dup()
> $stderr.close() # this will affect STDERR, too.
> begin
> yield
> ensure
> $stderr = save.dup()
> # SIDE EFFECT: the file descriptor STDERR points to will be valid
again
> end
> end
>
> However, this routine assumes that all file descriptors before
> $stderr are used. This is the case unless $stdin or $stdout have
> been closed. Is there something like dup2() in Ruby?

This routine has a totally different problem: closing $stderr make the lib
function abort because it will get an exception on writing to $stderr.
$stderr has to be something that is open.

Regards

robert