Practice of Programming

プログラム とか Linuxとかの話題

Archive::Zipでスカラを展開

$targetにzipの中身が入っていて、そいつを展開したい。
Archive::Zipには、readFromFileHandleってのが用意されている(ファイルから読む場合は、readメソッド)ので、
スカラリファレンスをopenでやってみたけど...

use Archive::Zip;

my $zip = new Archive::Zip;

open my $fh, "<", \$target or die $!;
$zip->readFromFileHandle($fh) == AZ_OK or die;

foreach my $member ($zip->members) {
    $zip->extractMember($member);
}

ダメらしい。file not seekable と言われる。


下記ですね。

        return _error('file not seekable')
          unless _isSeekable($fh);

_isSeekableは、

sub _isSeekable    # Archive::Zip
{
        my $fh = shift;

        if ( UNIVERSAL::isa( $fh, 'IO::Scalar' ) )
        {
                return 0;
        }
        elsif ( UNIVERSAL::isa( $fh, 'IO::String' ) )
        {
                return 1;       
        }
        elsif ( UNIVERSAL::can( $fh, 'stat' ) )
        {
                return -f $fh;
        }
        return UNIVERSAL::can( $fh, 'seek' );
}

ちうことのようです。

open my $fh, "<", \$target or die $!;

の$fhは、いずれのテストにも通らないので、アウトだと。
で、IO::StringならOKということなので、素直にそちらでいきます。
open消し忘れてたので、コメントに

use Archive::Zip qw/:ERROR_CODES/;
use IO::String;

my $zip = new Archive::Zip;

# open my $fh, "<", \$target or die $!;
$zip->readFromFileHandle(IO::String->new($target)) == AZ_OK or die;

foreach my $member ($zip->members) {
    $zip->extractMember($member);
}

めでたく、OK。


readFromScalarref とかいうのを作ればいいんではないだろうかとか。

sub readFromScarref {
   my $self = shift;
   my $rs   = shfit;
   return $self->readFromFileHandle(IO::String->new($$rs));
}

提案はしてみたけど、返事くるかなぁ。rtのがいいのかな?