From: Robert Dober Date: 2006-03-25T00:32:31+09:00 Subject: Re: redirecting stdout to a String ------=_Part_8906_1449303.1143214331645 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On 3/24/06, Mark Volkmann wrote: > > On 3/24/06, James Edward Gray II wrote: > > On Mar 24, 2006, at 7:50 AM, Mark Volkmann wrote: > > > > > I wrote a unit test for a method that writes to stdout. I got it to > > > work, but I'm not sure my approach was the best. Is there a more > > > recommended way to do this? > > > > > > # Create a String with a singleton write method > > > # that allows it to take the place of stdout. > > > actual =3D ''' > > > def actual.write(data); self << data; end > > > > See the standard library, StringIO. > > Thanks! I have that working, but it's not clear to me how that is > better. In fact, it seems to take more code to do it that way. I now > have this. > > require 'stringio' > > sio =3D StringIO.new > old_stdout, $stdout =3D $stdout, sio > # Invoke method to test that writes to stdout. > $stdout =3D old_stdout # restore stdout > actual =3D sio.string > > Am I overcomplicating this? > > -- > R. Mark Volkmann > Object Computing, Inc. > > I made a benchmark of both solutions, but I was surprised how small the difference was. StringIO is faster, as I expected. See below for results. Apart from that I feel that stringio will have adavantages for giving you a complete API. But for a quick solution the singleton method seems elegant and I like it a lot, after all you do not require( which was not benchmarked!!!) 'stringio' and run a core script. But for reusable code I'll defenitely go for stringio. Cheers Robert ---------------------------------- 8< ------------------------------------- cat stringio.rb;ruby stringio.rb #!/usr/bin/env ruby # Create a String with a singleton write method # that allows it to take the place of stdout. require 'benchmark' require 'stringio' n =3D 500000 r1 =3D r2 =3D nil Benchmark.bm do |bm| bm.report "single string" do actual =3D '' def actual.write(data); self << data.to_s; end old_stdout, $stdout =3D $stdout, actual n.times{ |i| $stdout.write i } $stdout =3D old_stdout r1=3D actual end # do bm.report "stringio " do sio =3D StringIO.new old_stdout, $stdout =3D $stdout, sio n.times{ |i| $stdout.write i} # Invoke method to test that writes to stdout. $stdout =3D old_stdout # restore stdout r2 =3D sio.string end # do end # do raise Exception unless r1 =3D=3D r2 user system total real single string 1.460000 0.000000 1.460000 ( 1.823057) stringio 1.320000 0.010000 1.330000 ( 1.828039) -- Deux choses sont infinies : l'univers et la b=EAtise humaine ; en ce qui concerne l'univers, je n'en ai pas acquis la certitude absolue. - Albert Einstein ------=_Part_8906_1449303.1143214331645--