I already discovered that I can redirect $stdout just by pointing it at
a new file handle. But what I really want is to have the output
continue to STDOUT but ALSO go into my logging file along with a pile of
trace data. This is very similar to the Unix program 'tee'
Any suggestions?
···
--
Posted via http://www.ruby-forum.com/.
Sure. I showed how to replace $stdout in a post earlier today:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/245389
Just make a TeeIO object and stick it in that variable.
Lets us know if you are still stuck and we will give more help.
James Edward Gray II
···
On Mar 26, 2007, at 4:44 PM, Larry Fast wrote:
I already discovered that I can redirect $stdout just by pointing it at
a new file handle. But what I really want is to have the output
continue to STDOUT but ALSO go into my logging file along with a pile of
trace data. This is very similar to the Unix program 'tee'
Any suggestions?
Funny, I was just writing this code last night for the latest release
of ci_reporter. Have a look at the CI::Reporter::OutputCapture class
at line 11, and its usage on line 50:
http://tinyurl.com/29rhqj
Cheers,
/Nick
···
On 3/26/07, Larry Fast <lfast@mdsi.ca> wrote:
I already discovered that I can redirect $stdout just by pointing it at
a new file handle. But what I really want is to have the output
continue to STDOUT but ALSO go into my logging file along with a pile of
trace data. This is very similar to the Unix program 'tee'
Any suggestions?
Hi Larry,
I realize this is *not* what you are asking, but in the interest of self-promotion (*gag*), here's a Ruby app I wrote that functions as a replacement for 'tee'
http://www.awk-fu.com/software/mux/
Getting back on topic now,
JD
···
On Mar 26, 2007, at 5:44 PM, Larry Fast wrote:
I already discovered that I can redirect $stdout just by pointing it at
a new file handle. But what I really want is to have the output
continue to STDOUT but ALSO go into my logging file along with a pile of
trace data. This is very similar to the Unix program 'tee'
Any suggestions?
--
Posted via http://www.ruby-forum.com/\.
I already discovered that I can redirect $stdout just by
pointing it at a new file handle. But what I really want is
to have the output continue to STDOUT but ALSO go into my
logging file along with a pile of trace data. This is very
similar to the Unix program 'tee'
Here's the code of my own log library that does exactly what
you want.
gegroet,
Erik V. - http://www.erikveen.dds.nl/
···
----------------------------------------------------------------
["$stdout", "$stderr"].each do |std|
io = eval(std)
old_write = io.method(:write)
class << io
self
end.module_eval do
define_method(:write) do |text|
unless text =~ /^[\r\n]+$/ # Because puts calls twice.
File.open("logfile.log", "a") do |f|
f.puts [std[1..-1].upcase, caller[2], text].join(" ")
end
end
old_write.call(text)
end
end
end
$stdout.puts "text on stdout"
$stderr.puts "text on stderr"
----------------------------------------------------------------
class TeeIO
attr 'tee'
def initialize tee, io
@tee = tee
@io = io
end
def << buf
@tee << buf
@io << " "
@io << buf
end
end
-a
···
On Tue, 27 Mar 2007, Nick Sieger wrote:
On 3/26/07, Larry Fast <lfast@mdsi.ca> wrote:
I already discovered that I can redirect $stdout just by pointing it at
a new file handle. But what I really want is to have the output
continue to STDOUT but ALSO go into my logging file along with a pile of
trace data. This is very similar to the Unix program 'tee'
Any suggestions?
Funny, I was just writing this code last night for the latest release
of ci_reporter. Have a look at the CI::Reporter::OutputCapture class
at line 11, and its usage on line 50:
c a l d e r s p h e r e . n e t
Cheers,
/Nick
--
be kind whenever possible... it is always possible.
- the dalai lama
Nick Sieger wrote:
Have a look at the CI::Reporter::OutputCapture class
at line 11, and its usage on line 50:
c a l d e r s p h e r e . n e t
Thanks Nick,
This is *almost* what I want. I want to MERGE $stdout, $stderr and my
debugging output. If I change @captured_io to @@captured_io and move it
outside Initialize, does everything else stay the same?
The only changed section is then:
class OutputCapture < DelegateClass(IO)
def initialize(io, &assign)
super
@delegate_io = io
@assign_block = assign
@assign_block.call self
end
@@captured_io = StringIO.new
Also, in your invocation on line 50, is {|io| $stdio = io} only used for
resetting $stdout back to normal. Nothing else?
···
--
Posted via http://www.ruby-forum.com/\.
Erik Veenstra wrote:
["$stdout", "$stderr"].each do |std|
io = eval(std)
old_write = io.method(:write)
class << io
self
end.module_eval do
old_write.call(text)
Thanks Eric,
That's a very elegant solution. Does IO funnel all it's writes through
"write"? Including things like putc? And where would I look to find this
out? Is it only in the source code?
Last question: what does "self" do on the line below "class << io"
···
--
Posted via http://www.ruby-forum.com/\.
For the initial replacement as well as the resetting back to normal,
see the #initialize method where it is also used.
Seems like your mutation to use a @@class var should work fine.
/Nick
···
On 3/26/07, Larry Fast <lfast@mdsi.ca> wrote:
Nick Sieger wrote:
> Have a look at the CI::Reporter::OutputCapture class
> at line 11, and its usage on line 50:
> c a l d e r s p h e r e . n e t
Thanks Nick,
This is *almost* what I want. I want to MERGE $stdout, $stderr and my
debugging output. If I change @captured_io to @@captured_io and move it
outside Initialize, does everything else stay the same?
The only changed section is then:
class OutputCapture < DelegateClass(IO)
def initialize(io, &assign)
super
@delegate_io = io
@assign_block = assign
@assign_block.call self
end
@@captured_io = StringIO.new
Also, in your invocation on line 50, is {|io| $stdio = io} only used for
resetting $stdout back to normal. Nothing else?
I rarely drink tea. Can we please also have a CoffeaIO? Thank you!
SCNR
robert
···
On 27.03.2007 03:54, ara.t.howard@noaa.gov wrote:
On Tue, 27 Mar 2007, Nick Sieger wrote:
On 3/26/07, Larry Fast <lfast@mdsi.ca> wrote:
I already discovered that I can redirect $stdout just by pointing it at
a new file handle. But what I really want is to have the output
continue to STDOUT but ALSO go into my logging file along with a pile of
trace data. This is very similar to the Unix program 'tee'
Any suggestions?
Funny, I was just writing this code last night for the latest release
of ci_reporter. Have a look at the CI::Reporter::OutputCapture class
at line 11, and its usage on line 50:
c a l d e r s p h e r e . n e t
Cheers,
/Nick
class TeeIO
attr 'tee'
def initialize tee, io
@tee = tee
@io = io
end
def << buf
@tee << buf
@io << " "
@io << buf
end
end
Erik Veenstra wrote:
> ["$stdout", "$stderr"].each do |std|
> io = eval(std)
> old_write = io.method(:write)
> class << io
> self
> end.module_eval do
> old_write.call(text)
[snip]
Last question: what does "self" do on the line below "class << io"
>> class Rectangle; end
=> nil
>> r = Rectangle.new
=> #<Rectangle:0x2c8bfe8>
>> class << r; self; end
=> #<Class:#<Rectangle:0x2c8bfe8>>
The last expression in a block is the value of that block. In the
above, 'self' is used to 'return' the singleton class that was opened
with "class << io".
Various libraries have code like:
class Object
def singleton_class
class << self
self
end
end
end
abstracting the somewhat odd notation. With this, the original code
could be written as:
io.singleton_class.module_eval ...
···
On Mar 27, 10:55 am, Larry Fast <l...@mdsi.ca> wrote:
That's a very elegant solution. Does IO funnel all it's
writes through "write"? Including things like putc? And where
would I look to find this out? Is it only in the source code?
AFAIK, yes. Yes. In the source code. Probably.
Last question: what does "self" do on the line below "class
<< io"
The common way to define a method of an object is this:
class << an_object
def method
# ...
end
end
The problem is scope: variables declared before "class <<
an_object" aren't available within the "class << an_object"
block. (And variables declared before "def method" aren't
available within the "def method" block. But that can be worked
around by using "define_method(method)".) Defining a method
both within the context of "an_object" and within the local
scope of variables, can be achieved with this:
class << an_object
self
end.module_eval do
define_method(method) do
# ...
end
end
gegroet,
Erik V. - http://www.erikveen.dds.nl/
Nick Sieger wrote:
For the initial replacement as well as the resetting back to normal,
see the #initialize method where it is also used.
/Nick
OK, now I see it. I'm still quite green at Ruby.
... and in finish(), @captured_io.string is returning the captured text?
22 def finish
23 @assign_block.call @delegate_io
24 @captured_io.string
25 end
···
--
Posted via http://www.ruby-forum.com/\.
Yes, see the rdocs for StringIO: http://tinyurl.com/28mod3
/Nick
···
On 3/27/07, Larry Fast <lfast@mdsi.ca> wrote:
Nick Sieger wrote:
> For the initial replacement as well as the resetting back to normal,
> see the #initialize method where it is also used.
> /Nick
OK, now I see it. I'm still quite green at Ruby.
... and in finish(), @captured_io.string is returning the captured text?