Gregory Brown
8/12/2007 9:40:00 PM
On 8/12/07, Thomas Hafner <thomas@hafner.nl.eu.org> wrote:
> "Gregory Brown" <gregory.t.brown@gmail.com> wrote/schrieb <b37300880708111035o2af744e1g2411e061054095ee@mail.gmail.com>:
>
> > What problem do you need this for... it sounds like you could get by
> > with a different (and better) approach, but we'd need to know a little
> > more about what you're trying to do.
>
> Agreed that that there might be a better solution for the original
> problem, but sometimes an intermediate problem becomes interesting per
> se. Anyway, the original question is how to find a single, more
> abstract function replacing these ones:
>
> def with_output_to_string
> $stdout, tmp = StringIO.new, $stdout
> yield
> $stdout, tmp = tmp, $stdout
> tmp.rewind
> tmp.read
> end
>
> def with_error_to_string
> $stderr, tmp = StringIO.new, $stderr
> yield
> $stderr, tmp = tmp, $stderr
> tmp.rewind
> tmp.read
> end
>
> The only difference is $stdout vs. $stderr, so the idea was to pass
> :$stdout resp. :$stderr as parameter.
Interesting. Perhaps this is a direct translation of how you might do
this without an eval (untested):
module Kernel
def set_stdout(obj)
$stdout = obj
end
def set_stderr(obj)
$stderr = obj
end
end
def with_helper(msg)
temp = (msg == :stdout ? $stdout : $stderr)
send("set_#{msg}", StringIO.new)
yield
send("set_#{msg}",temp)
temp.rewind
temp.read
end
def with_output_to_string
with_helper(:stdout) { yield }
end
def with_error_to_string
with_helper(:stderr) { yield }
end
Of course, this doesn't sound like a great idea, as unless the real
problem is actually a whole lot more interesting, this is just
unnecessary generalization and doesn't clean things up any.
Are you looking to do this to test a codebase that writes to $stdout / $stderr?
It's perfectly reasonable to have a class or method definition like this:
class Foo
def initialize(out=$stdout,err=$stderr)
@out = out
@err = err
end
def print_to_stdout
@out.puts "something"
end
def print_to_stderr
@err.puts "something"
end
end
Now if you wanted to test that, you could pass in your StringIO
objects. Maybe you can draw some ideas from that, if not, it'd be
interesting to see what you're using this helper for.