Re: Appending print to a variable
by sauoq (Abbot) on Jul 30, 2003 at 16:50 UTC
|
perl -MIO::Scalar -le 'my $s; $SH = IO::Scalar->new(\$s); print $SH "f
+oo"; print $s'
Update: If you need to, you can even alias STDOUT to your IO::Scalar handle:
use IO::Scalar;
my $s;
my $SH = IO::Scalar->new(\$s);
{
local *STDOUT = $SH;
print "foo\n";
}
print $s;
That technique should enable you to avoid changing the current code.
Update 2: A better way to do that, rather than aliasing, is to use the tie interface provided by IO::Scalar. I probably should have recalled that, as I answered a similar question just over a month ago.
use IO::Scalar;
$string = tie *STDOUT, 'IO::Scalar';
print "foo\n";
print STDERR '$string: ', $string; # Must use stderr as stdout is t
+ied.
-sauoq
"My two cents aren't worth a dime.";
| [reply] [d/l] [select] |
Re: Appending print to a variable
by diotalevi (Canon) on Jul 30, 2003 at 16:49 UTC
|
Magic. This isn't tested code and if it doesn't work right off the bat, it at least demonstrates the idea here. Of course, the proper way to address this is not to print lots of stuff and capture it but instead rethink your organization so this isn't necessary.
use IO::Handle;
my $captured = IO::Handle->new;
tie *$captured, 'Capture::Handle',
handle => $captured
or die "Couldn't tie *CAPTURED: $!";
select CAPTURED;
print ....
my $captured = tied(*CAPTURED)->get_captured;
package Capture::STDOUT;
sub TIEHANDLE {
my $class = shift;
bless { @_ }, $class
}
sub set_handle { shift()->{'handle'} = shift }
sub get_handle { shift()->{'handle'} }
sub PRINT {
my $self = shift;
print $self->{'handle'} @_;
push @{$self->{'captured'}}, @_;
}
sub get_captured { @{shift()->{'captured'}} }
| [reply] [d/l] |
Re: Appending print to a variable
by skyknight (Hermit) on Jul 30, 2003 at 16:53 UTC
|
Execute this code, making note of the order of the printouts, and I think you'll get the idea.
#!/usr/bin/perl -w
use strict;
print "well, here we are!\n";
pipe(READ, WRITE);
my $original = select(WRITE);
print "and now we're here...\n";
close(WRITE);
select($original);
print "almost done...\n";
print while(<READ>);
| [reply] [d/l] |
|
|
Thanks alot for that. I even looked right at the pipe command but couldn't figure out how that would help. I've played with this a bit now and i think it will definitly do what i was looking for.
I was wondering if there were reasons to do this instead of aliasing print? any advantages/disadvantages i should be aware of?
___________
Eric Hodges
| [reply] |
|
|
It's not clear to me what you are proposing by "aliasing print". Could you clarify how you would do such a thing?
| [reply] |
|
|
(jeffa) Re: Appending print to a variable
by jeffa (Bishop) on Jul 30, 2003 at 16:50 UTC
|
Using sprintf will work, but i doubt that was what you
were looking for. How about something more OO like
IO::Scalar?
use strict;
use warnings;
use IO::Scalar;
my $out = IO::Scalar->new();
$out->print("hello world\n");
$out->print(qw(foo bar baz), "\n");
print $out;
But .... why reinvent a wheel? There are a plethora of
templating/embedding modules out there ... if you want to
embed your Perl (bleh!), then i recommend HTML::Mason or Apache::ASP.
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] [d/l] |
|
|
| [reply] |
Re: Appending print to a variable
by ChrisS (Monk) on Jul 30, 2003 at 16:37 UTC
|
Sounds like you might want sprintf...
$input = "Hello";
$output = sprintf("%s", $input . " World!");
print $output;
The above should print "Hello World!" and works with string data. You might need to check the perldocs for the various options in the format specification string ("%s").
perldoc -f sprintf
| [reply] [d/l] [select] |
|
|
<html>
<body>
<% #perl code here
setCookie(hello=>"already said");
print "Hello";
%>
</body>
</html>
Okay see how thats embeded in there? thats how it already is (except i'm makeing the scripter fudge it by doing "$OUT .=" in place of "print".) This lets me run all the code (to catch changes to cookies and headers, redirects, etc threwout the code) and have all the web page in a variable. Then I print the header and then print the variable. So i want the scripter to be able to use a regular print statment but i want the engine to catch the output of the print and append it to a variable to hold of printing.
Sorry for the confusion and thanks for the reply!
___________
Eric Hodges | [reply] [d/l] |
|
|
Thanks for the clarification... fortunately, everybody else seemed to catch what I missed, so you've got lots of possible answers.
| [reply] |
Re: Appending print to a variable
by cianoz (Friar) on Jul 30, 2003 at 17:08 UTC
|
Look at Apache::ASP
it does exactly the same thing aliasing print() to
$Response->Write()
| [reply] |
Re: Appending print to a variable
by BrowserUk (Patriarch) on Jul 30, 2003 at 18:58 UTC
|
If your using 5.8, you could also use an "in memory file". See perlfunc:open pod from 5.8 for details, but basically this involves closing STDOUT and then re-opening it to a scalar ref.
close STDOUT;
open STDOUT, '>', \my $buffer or die $!;
print ....; # This will append the output to $buffer
Alternatively, you could open another filehandle to a scalar and then select that filehandle as the default output stream prior to your print statements and select back when your ready to print output to STDOUT.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
| [reply] [d/l] |