summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrian d foy <brian.d.foy@gmail.com>2010-08-21 10:47:37 -0500
committerbrian d foy <brian.d.foy@gmail.com>2010-09-14 12:19:02 -0500
commit3cd7ab715194be8ea797d7f907f547c571ec12f2 (patch)
tree70127fba25325097c13f9330b6569c9fee4d0661
parentb67b790e7eb84923c1239217745e9fb6a50a1104 (diff)
downloadperl-3cd7ab715194be8ea797d7f907f547c571ec12f2.tar.gz
* How can I write() into a string?
+ Actually answer the question, now that we have filehandles to strings. + The swrite in perlform is no good anyway.
-rw-r--r--pod/perlfaq5.pod49
1 files changed, 48 insertions, 1 deletions
diff --git a/pod/perlfaq5.pod b/pod/perlfaq5.pod
index bd969f4393..683910e9e2 100644
--- a/pod/perlfaq5.pod
+++ b/pod/perlfaq5.pod
@@ -644,7 +644,54 @@ techniques to make it possible for the intrepid hacker.
=head2 How can I write() into a string?
X<write, into a string>
-See L<perlform/"Accessing Formatting Internals"> for an C<swrite()> function.
+(contributed by brian d foy)
+
+If you want to C<write> into a string, you just have to <open> a
+filehandle to a string, which Perl has been able to do since Perl 5.6:
+
+ open FH, '>', \my $string;
+ write( FH );
+
+Since you want to be a good programmer, you probably want to use a lexical
+filehandle, even though formats are designed to work with bareword filehandles
+since the default format names take the filehandle name. However, you can
+control this with some Perl special per-filehandle variables: C<$^>, which
+names the top-of-page format, and C<$~> which shows the line format. You have
+to change the default filehandle to set these variables:
+
+ open my($fh), '>', \my $string;
+
+ { # set per-filehandle variables
+ my $old_fh = select( $fh );
+ $~ = 'ANIMAL';
+ $^ = 'ANIMAL_TOP';
+ select( $old_fh );
+ }
+
+ format ANIMAL_TOP =
+ ID Type Name
+ .
+
+ format ANIMAL =
+ @## @<<< @<<<<<<<<<<<<<<
+ $id, $type, $name
+ .
+
+Although write can work with lexical or package variables, whatever variables
+you use have to scope in the format. That most likely means you'll want to
+localize some package variables:
+
+ {
+ local( $id, $type, $name ) = qw( 12 cat Buster );
+ write( $fh );
+ }
+
+ print $string;
+
+There are also some tricks that you can play with C<formline> and the
+accumulator variable C<$^A>, but you lose a lot of the value of formats
+since C<formline> won't handle paging and so on. You end up reimplementing
+formats when you use them.
=head2 How can I open a filehandle to a string?
X<string> X<open> X<IO::String> X<filehandle>