I have code that prints to stdout (using puts and/or print).
I’m loading the code from a file (pretty much the way rake handles
rakefiles) and would like to capture the output from the loaded code.
I don’t want to redirect stdout into a file or anywhere else, I need the
output in a string.
—file1.rb
puts “Output of meaningful code omitted”
—loader.rb
begin
###do some magic to get the stdout from this point on into a string
load file1.rb
###do some more magic to put stdout back where it was.
end
Has anyone a solution for this?
(Now that I think of it would StringIO do for stdout redirection?)
Cheers,
V.-
http://www.braveworld.net/riva
2006/5/17, Damphyr [email protected]:
begin
###do some magic to get the stdout from this point on into a string
load file1.rb
###do some more magic to put stdout back where it was.
end
Has anyone a solution for this?
You can use popen but then your code is in another process.
(Now that I think of it would StringIO do for stdout redirection?)
Yes, but you then must explicitely use a receiver with those puts
statements as Kernel.puts still sends to $DEFOUT.
Kind regards
robert
PS: Using Log4r may be an option, too.
Damphyr wrote:
I have code that prints to stdout (using puts and/or print).
I’m loading the code from a file (pretty much the way rake handles
rakefiles) and would like to capture the output from the loaded code.
I don’t want to redirect stdout into a file or anywhere else, I need the
output in a string.
—file1.rb
puts “Output of meaningful code omitted”
—loader.rb
begin
###do some magic to get the stdout from this point on into a string
load file1.rb
###do some more magic to put stdout back where it was.
end
How about do it this way:
s = ruby file1.rb
, you don’t need to load file1.rb in .
Best Regards.
Robert K. wrote:
(Now that I think of it would StringIO do for stdout redirection?)
Yes, but you then must explicitely use a receiver with those puts
statements as Kernel.puts still sends to $DEFOUT.
Yes, but I can change Kernel#puts
These files are tests, written using a simple DSL and then run just like
rake runs it’s rakefiles.
So I am loath to require receivers for puts or any other logging
facility (I am the only one in my project comfortable with Ruby,
although everyone agrees that it saves them a lot of time and trouble).
popen was my obvious choice (it’s already in use in this whole mess) but
I was wondering if there was another way.
Oh, well.
Cheers,
V.-
–
http://www.braveworld.net/riva
2006/5/17, Damphyr [email protected]:
Yes, but I can change Kernel#puts
You can use a simple mock method for this. See
http://groups.google.com/group/comp.lang.ruby/msg/cb4aeb65311e3a8e
The original method is restored on exit.
Cheers
robert
Daniel H. wrote:
2006/5/17, Damphyr [email protected]:
begin
###do some magic to get the stdout from this point on into a string
load file1.rb
###do some more magic to put stdout back where it was.
end
Has anyone a solution for this?
require ‘stringio’
stdout = StringIO.new
$stdout = stdout
load “file1.rb”
$stdout = STDOUT
stdout.rewind
puts “got: #{stdout.read}” # => got: Output of meaningful code omitted
– Daniel
I am wondering whether Ruby has something similar to C++ stringstream,
and you give the answer. It is happy to see it.
Best regards.
uncutstone
2006/5/17, Damphyr [email protected]:
begin
###do some magic to get the stdout from this point on into a string
load file1.rb
###do some more magic to put stdout back where it was.
end
Has anyone a solution for this?
require ‘stringio’
stdout = StringIO.new
$stdout = stdout
load “file1.rb”
$stdout = STDOUT
stdout.rewind
puts “got: #{stdout.read}” # => got: Output of meaningful code omitted
– Daniel
Here’s another alternative.
Create a string object to receive the output.
dest = ‘’
Add a write method to this string object.
def dest.write(data); self << data; end
old_stdout, $stdout = $stdout, dest
Invoke code that uses puts.
Restore stdout.
$stdout = old_stdout
###do some magic to get the stdout from this point on into a string
All you have to do is assign a different IO Object to the global
$stdout variables and Kernel.puts will write to that IO object.
The real
standard out of the process will be available in the STDOUT
constant, in case you need definate access to it, though you’d
probably want to save a copy of the original value of $stdout, you
never know…
old_stdout=$stdout
$stdout=File.new(…)
Do a bunch of stuff that shouldn’t log to the console
$stdout=old_stdout # everything back to normal…
same applies to $stderr STDERR
-tim
Mark V. wrote:
Here’s another alternative.
Create a string object to receive the output.
dest = ‘’
Add a write method to this string object.
def dest.write(data); self << data; end
old_stdout, $stdout = $stdout, dest
Invoke code that uses puts.
Restore stdout.
$stdout = old_stdout
I think this is what duck type means. It’s really a good example of duck
type, isn’t it?
Best regards.
uncutstone
Quoting [email protected], on Wed, May 17, 2006 at 07:49:34PM +0900:
begin
###do some magic to get the stdout from this point on into a string
load file1.rb
###do some more magic to put stdout back where it was.
end
Has anyone a solution for this?
(Now that I think of it would StringIO do for stdout redirection?)
Yes,
% ruby -rstringio -e’$stdout = StringIO.new; puts “hello”; $stderr.puts
$stdout.string’
hello
Eric H. wrote:
On May 17, 2006, at 5:26 AM, Mark V. wrote:
$stdout = stdout
Add a write method to this string object.
def dest.write(data); self << data; end
How is this better than using StringIO?
IMHO, by using StringIO, you pay for something useless in this case but
maybe usefule anywhere else. I mean StringIO has many methods(e.g.
read,close,rewind) besides write , but “def dest.write…” has just
the function you want. You just pay for what you want. Isn’t it better?
Best regards,
uncutstone
On May 17, 2006, at 12:10 PM, uncutstone wu wrote:
but
maybe usefule anywhere else. I mean StringIO has many methods(e.g.
read,close,rewind) besides write , but “def dest.write…” has just
the function you want.
You’re confusing unused with useless. I almost never use Hash#index
but that doesn’t make it useless.
You just pay for what you want. Isn’t it better?
No. Using StringIO is more robust and more maintainable than using a
String with custom methods. If I want to puts or print then I have
to add those methods. If I just used StringIO I won’t have to do
anything.
I’ve found that having to maintain custom code is usually more
expensive than reusing what’s available.
–
Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant
http://trackmap.robotcoop.com
On 5/17/06, Eric H. [email protected] wrote:
No. Using StringIO is more robust and more maintainable than using a
String with custom methods. If I want to puts or print then I have
to add those methods. If I just used StringIO I won’t have to do
anything.
You don’t have to add a puts method to the String object in order to
have puts calls append to it. puts ends up calling write. I assume
print does the same, but I’m not sure.
On May 17, 2006, at 5:26 AM, Mark V. wrote:
$stdout = stdout
Add a write method to this string object.
def dest.write(data); self << data; end
How is this better than using StringIO?
–
Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant
http://trackmap.robotcoop.com
On May 17, 2006, at 1:41 PM, Mark V. wrote:
print does the same, but I’m not sure.
The Kernel methods have this behavior, yes, but this is not a general
solution.
$ ruby
s = ‘’
def s.write(d) self << d; end
$stdout = s
$stdout.puts ‘hi’
-:4: private method `puts’ called for “”:String (NoMethodError)
–
Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant
http://trackmap.robotcoop.com
Mark V. wrote:
On 5/17/06, Eric H. [email protected] wrote:
No. Using StringIO is more robust and more maintainable than using a
String with custom methods. If I want to puts or print then I have
to add those methods. If I just used StringIO I won’t have to do
anything.
You don’t have to add a puts method to the String object in order to
have puts calls append to it. puts ends up calling write. I assume
print does the same, but I’m not sure.
Yes, print does the same.
main.rb:
strio = “”
def strio.write(data)
self << data
end
$stdout = strio
load ‘expansion.rb’
$stdout = STDOUT
puts “Get: #{strio}”
expansion.rb
print “hello”
result:
Get: hello