expat has asked for the wisdom of the Perl Monks concerning the following question:

Here is my code:

use v5.16; use XML::Simple; my $HOME = $ENV{HOMEPATH}; my $fn = "$HOME" . "\\documents\\output.txt"; open (my $out,">$fn") or die "$fn open failed for write $!"; my @fields = qw(name medium subject url); # read in the xml from file my $site_xml = XMLin( 'C:/Users/mark/Documents/sitesout.xml', forcearray => 1 ); # print a header for the output print($out, '-' x 70, "\n"); printf ($out,"%-35s%-15s%8s%8s\n", 'name', 'medium', 'subject', 'url' +); print($out, '-' x 70, "\n"); # fetch the data, dereferencing (probably incorrectly) for my $site ( @{ $site_xml->{site} } ) { # try to print to a file printf ($out, "%-35s", $site->{ ( $fields[0] ) }->[0] ); printf ($out, "%-15s", $site->{ ( $fields[1] ) }->[0] ); printf($out, "%8s", $site->{ ( $fields[2] ) }->[0] ); printf($out, "%8s\n", $site->{ ( $fields[3] ) }->[0] ); #print to standard output #printf ("%-35s", $site->{ ( $fields[0] ) }->[0] ); #printf ("%-15s", $site->{ ( $fields[1] ) }->[0] ); #printf("%8s", $site->{ ( $fields[2] ) }->[0] ); #printf("%8s\n", $site->{ ( $fields[3] ) }->[0] ); } close $out;

I'm trying to learn something about processing XML in Perl, starting with the XML::Simple package. The entire program is in the code I've posted here. You'll see that there are 2 sections of code to print the info captured by XMLin(). One is a printf to standard output (presently commented out), the other printf to a file.

Printing to standard output gives the expected results. Printing to a file yields only 'GLOB(0x60d658)' repeated more times than I care to count, and a 0 byte file created.

I am perplexed, any pointers would be appreciated.

I'm on a Windows 7 64 bit laptop, running activestate perl v5.16

Replies are listed 'Best First'.
Re: XML::Simple and output
by Athanasius (Archbishop) on Feb 16, 2014 at 04:30 UTC

    This is one of the idiosyncrasies of Perl syntax: when printing to a filehandle, there must be no comma between the filehandle and the format string. See printf.

    Update 1: See also the comment at the end of brian_d_foy’s 2005 thread Perl oddities:

    You don't put a comma between the filehandle name and the list you give to print. I've just always thought that was odd, and I go out of my way to point it out to people in Perl classes. I don't have a problem with this while I code, but I still think it's an odd corner of syntax.

    Update 2: With the comma, Perl thinks the filehandle is the first thing to be printed, so it stringifies it and prints the string to STDOUT. You can see this by doing it explicitly, like this:

    18:09 >perl -we "open my $fh, '<', 'Test1.txt'; printf '%s', $fh;" GLOB(0x2fc0a4) 18:13 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      I think this is easier to memorize, if you write
      print$fh "whatever you want to print";
      so that it is optically a single "command word"...
        I still prefer
        print {$fh} "whatever";
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Is my face red!

      The hours that comma cost me

      Thanks much