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

I'm trying to use XML::Writer together with IO::Compress::Gzip like this:

my $doc, $zipped; my $writer = new XML::Writer(OUTPUT=>\$doc, ...); # write stuff ... $writer->end(); gzip \$doc => \$zipped;
Unfortunately, the call to gzip dies with the message “illegal input parameter”

However, if I change the last line to:

my $copy = $doc; gzip \$copy => \$zipped;
everything works fine. What's going on?

Replies are listed 'Best First'.
Re: XML::Writer oddness
by ikegami (Patriarch) on Feb 24, 2010 at 17:39 UTC

    XML::Writer blesses $doc for some reason. I presume IO::Compress::gzip checks for that even though it would have no effect in this case. Copying $doc doesn't copy the blessing.

    use strict; use warnings; use Devel::Peek qw( Dump ); use Scalar::Util qw( blessed ); use XML::Writer qw( ); my $writer = new XML::Writer(OUTPUT => \my $doc); $writer->startTag("root"); $writer->startTag("foo"); $writer->endTag("foo"); $writer->endTag("root"); $writer->end(); Dump $doc; print(blessed(\$doc)?1:0, "\n"); # 1 my $copy = $doc; Dump $copy; print(blessed(\$copy)?1:0, "\n"); # 0
    SV = PVMG(0x18c5614) at 0x182a39c REFCNT = 2 FLAGS = (PADMY,OBJECT,POK,pPOK) IV = 0 NV = 0 PV = 0x1922fbc "<root><foo></foo></root>\n"\0 CUR = 25 LEN = 28 STASH = 0x19154b4 "XML::Writer::_String" 1 SV = PVMG(0x18c5654) at 0x1915784 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) IV = 0 NV = 0 PV = 0x1925184 "<root><foo></foo></root>\n"\0 CUR = 25 LEN = 28 0

      Thanks. That makes sense. Courtesy of XML::Writer, \$doc is a reference to an XML::Writer::_String object instead of a reference to a scalar, as I expected.

      gzip does lots of different things depending on its first arg. Of course, the docs for Gzip say that if the first arg isn't something it expects (a filename, filehandle, scalar reference, array reference, or an Input FileGlob string), it will return undef. Instead, it dies. How rude.

        \$doc is a reference to an XML::Writer::_String object instead of a reference to a scalar,

        Well, it's both, seeing as $doc is a scalar. And furthermore, the contents of the scalar are obviously meant to be used as a string (If not, $doc would be given a reference.) So don't be afraid to use it as a string.