is a useful library for working with tar archives from Perl.
Unfortunately, one thing it doesn’t allow is using data from memory as
the archive. From the TODO section:
Allow archives to be passed in as string
Currently, we only allow opened filehandles or filenames, but not
strings. The internals would need some reworking to facilitate
Fortunately, it does allow you to use a filehandle. I’ve previously
mentioned about how useful the IO::Handle subsystem in perl is. And we
should be able to use it in this case. The module we’ll want is
IO::String, which is a IO::Handle over a perl scalar. We can use it:
my $tar = new Archive::Tar(new IO::String($data));
Unfortunately when we run this now we get:
Cannot read compressed format in tar-mode at Foo.pm line 41 No data could be read from file at Foo.pm line 41
It turns out that this is because Archive::Tar uses IO::Zlib
internally if the file isn’t uncompressed, but this doesn’t provide the
ability to uncompress from a filehandle. The answer is to uncompress the
data before passing it to Archive::Tar and the easiest way to do this is
to use the IO::Uncompress::Gunzip module, so we can rewrite our code
my $tar = new Archive::Tar(new IO::Uncompress::Gunzip(new IO::String($data)));
Now when you run the script, Archive::Tar has an uncompressed tar
stream. Yet another situation where IO::Handles comes to the rescue.
A couple of comments. First, is there a reason why you’re saying “new Archive::Tar” instead of “Archive::Tar->new()”? That syntxa can get you unstuck in a few places if you’re not careful. See perlobj/Indirect Object Syntax for details.
Secondly, there’s no need to use a module for getting a filehandle for a string any more. You can say something like this since Perl 5.8.
open my $fh, ‘<‘, $str;
(I’m not sure if that should be followed with “or die()” — I don’t think anything could go wrong there).