M
Matthew Braid
Hi all,
I've just found a rather annoying problem with Archive::Zip.
I'm using temp files (via File::Temp's tempfile function) to store
zipped data from a database. Unfortunately it seems there was a change
in the last version that makes Archive::Zip want a seekable handle for
the readFromFileHandle, and Archive::Zip doesn't want to believe that
temp files are seekable.
I checked the _isSeekable function in Archive::Zip:
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' );
}
The problem is that the -f $fh is wrapped in a UNIVERSAL::can(). I've
never had much luck with UNIVERSAL::can(), and sure enough it's failing
here. A quick demo shows this:
use File::Temp qw/tempfile/;
my $fh = tempfile(UNLINK => 1);
print "Can stat? ", (UNIVERSAL::can($fh, 'stat') ? 1 : 0), "\n";
print "Is file? ", (-f $fh ? 1 : 0), "\n";
Can stat? 0
Is file? 1
A better way to do this test would be to use eval. Instead of:
elsif ( UNIVERSAL::can( $fh, 'stat' ) )
{
return -f $fh;
}
use:
return 1 if eval {-f $fh};
BTW, has anyone reliably used UNIVERSAL::can? It never seems to work for
me...
MB
I've just found a rather annoying problem with Archive::Zip.
I'm using temp files (via File::Temp's tempfile function) to store
zipped data from a database. Unfortunately it seems there was a change
in the last version that makes Archive::Zip want a seekable handle for
the readFromFileHandle, and Archive::Zip doesn't want to believe that
temp files are seekable.
I checked the _isSeekable function in Archive::Zip:
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' );
}
The problem is that the -f $fh is wrapped in a UNIVERSAL::can(). I've
never had much luck with UNIVERSAL::can(), and sure enough it's failing
here. A quick demo shows this:
use File::Temp qw/tempfile/;
my $fh = tempfile(UNLINK => 1);
print "Can stat? ", (UNIVERSAL::can($fh, 'stat') ? 1 : 0), "\n";
print "Is file? ", (-f $fh ? 1 : 0), "\n";
Can stat? 0
Is file? 1
A better way to do this test would be to use eval. Instead of:
elsif ( UNIVERSAL::can( $fh, 'stat' ) )
{
return -f $fh;
}
use:
return 1 if eval {-f $fh};
BTW, has anyone reliably used UNIVERSAL::can? It never seems to work for
me...
MB