SPUG: Is format evil?

Yitzchak Scott-Thoennes sthoenna at efn.org
Fri Mar 9 12:27:14 PST 2007


Ryan wrote:
> Does anybody know a painless way to send a format to two places at once?
> I'd like for the format to go to STDOUT and an open filehandle.  For
> example:
>
> sub displayUpgradeConfig(){
>
>     my ($k, $v);
>     my $c = 1;
>
> format STDOUT =
>       blade @<< :   @<<<<<<<<<<<<<<<< : @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>             $c,     $k,                 $v
> .
>
>
>     foreach $i (\%blade1, \%blade2, \%blade3, \%blade4){
>
>         while ( ($k, $v) = each (%$i)){
>             write;
>             write $logFH;
>         }
>
>         $c++;
>     }
> }
>
>
> Notice the two "write" lines.  Possible?  I'm pulling my hair out?  The
> above code produces this error:
>
> Undefined format "Symbol::GEN0" called at ./clusterInstaller line 531.

The format (and top-of-page format) used for each filehandle defaults to
a name based on the filehandle, but you can change it.  Try:

   use IO::Handle;
   $logFH->format_name( $~ );
   $logFH->format_top_name( $^ );

at some point after you've opened $logFH.

Or you can avoid write and named formats, and build a string with formline
to print anywhere you want.

Or (in 5.8.0 or later), you can copy formats from one filehandle to
another by assigning format references to globs:

   *$logFH = *STDOUT{FORMAT};

though this doesn't work so well for _top formats for "anonymous" globs
like your $logFH (generated by Symbol::gensym).


More information about the spug-list mailing list