Kevin Ryde
and 1 contributors


Filter::gunzip - gunzip Perl source code for execution


 perl -MFilter::gunzip

 # or in a script
 use Filter::gunzip;
 ... # inline gzipped source code bytes


This filter uncompresses gzipped Perl code at run-time. It can be used from the command line to run a .pl.gz file,

    perl -MFilter::gunzip

Or in a self-uncompressing executable beginning with a use Filter::gunzip and gzip bytes immediately following that line,

    use Filter::gunzip;
    ... raw gzip bytes here

The filter is implemented one of two ways. For the usual case that Filter::gunzip is the first filter and PerlIO is available then push a PerlIO::gzip layer. Otherwise add a block-oriented source filter per perlfilter. In both cases the uncompressed code can apply further source filters in the usual way.

DATA Handle

The __DATA__ token ("Special Literals" in perldata) and DATA handle can be used in the compressed source, but only some of the time.

For the PerlIO case the DATA handle is simply the input, including the :gzip uncompressing layer, positioned just after the __DATA__ token. It can be read in the usual way. Note however PerlIO::gzip as of its version 0.18 cannot dup() or seek() which limits what can be done with the DATA handle. In particular for example SelfLoader requires seek() and so doesn't work on compressed source. (Duping and seeking in PerlIO::gzip are probably both feasible, though seeking backward might be slow.)

For the filter case DATA doesn't work properly. Perl stops reading from the source filters at the __DATA__ token, because that's where the source ends. But a block oriented filter like Filter::gunzip may read ahead in the input file which means the position of the DATA handle is unpredictable, especially if there's more than one block-oriented filter stacked up.

Further Details

Perl source is normally read without CRLF translation (in Perl 5.6.1 and up at least). If Filter::gunzip sees a :crlf layer on the input it pushes the :gzip underneath that, since the CRLF is almost certainly meant to apply to the text, not to the raw gzip bytes. This should let it work with the forced PERLIO=crlf suggested by README.cygwin (see "PERLIO" in perlrun).

The gzip format has a CRC checksum at the end of the data. This might catch subtle corruption in the compressed bytes, but as of Perl 5.10 the parser usually doesn't report a read error and in any case the code is compiled and BEGIN blocks executed immediately, before the CRC is reached, so corruption will likely provoke a syntax error or similar first.

Only the gzip format (RFC 1952) is supported. Zlib format (RFC 1950) differs only in the header, but PerlIO::gzip (version 0.18) doesn't allow it. The actual gunzip program can handle some other formats, like Unix .Z compress, but those formats are probably best left to other modules.

The bzip2 format could be handled by a very similar filter, if .pl.bz2 files were used. But its decompressor consumes at least 2.5 Mbytes of memory, so if choosing that format there'd have to be a big disk saving before it was worth that much memory at runtime.


Filter::exec and the zcat program can do the same thing, either from the command line or self-expanding,

    perl -MFilter::exec=zcat

Because Filter::exec is a block-oriented filter (as of its version 1.37) a compressed __DATA__ section within the script doesn't work.

PerlIO::gzip can be applied to a script with the open pragma and a require of the script filename. For example something like the following from the command line. Since the open pragma is lexical it doesn't affect other later loads or opens.

    perl -e '{use open IN=>":gzip";require shift}' \
   arg1 arg2

It doesn't work to set a PERLIO environment variable for a global :gzip layer, eg. PERLIO=':gzip(autopop)', because the default layers in the PERLIO environment variable are restricted to Perl builtins (see "PERLIO" in perlrun).


PerlIO::gzip, PerlIO, Filter::Util::Call, Filter::exec, gzip(1), zcat(1), open

The author's compile-command-default.el can setup Emacs to run a .pl.gz by either Filter::gunzip or other ways (according to what's available).



Filter-gunzip is Copyright 2010, 2011, 2013, 2014 Kevin Ryde

Filter-gunzip is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Filter-gunzip is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Filter-gunzip. If not, see <>.