http://www.perlmonks.org?node_id=853788

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

I am trying:
my $zip = Archive::Zip->new(); $zip->addFile($renamed_file)->desiredCompressionLevel(0); if( $zip->writeToFileNamed($zip_filename) != AZ_OK ) { print "wr +ite error...$!"; } print "Added $renamed_file to $zip_filename\n"; }
and getting:
Can't call method "desiredCompressionLevel" on an undefined value at / +home/fds/lang/perl/fdsPerl-20100809/lib/site_perl/5.12.1/Archive/Zip/ +Archive.pm line 249. at /home/fds/lang/perl/fdsPerl-20100809/lib/site_perl/5.12.1/Archive/ +Zip/Archive.pm line 249 Archive::Zip::Archive::addFile('Archive::Zip::Archive=HASH(0x1 +49ff318)', 'vm.don') called at ve.pl line 75

Replies are listed 'Best First'.
Re: problem with Archive::Zip
by Utilitarian (Vicar) on Aug 09, 2010 at 12:06 UTC
    From Archive::Zip
    If the name given does not represent a readable plain file or symbolic + link, undef will be returned
    It looks as though $renamed_file is not "a readable plain file or symbolic link".

    Try wrapping your code with this check to be sure:

    if ( ( -r $renamed_file )&& ( ( -f $renamed_file ) || ( -l $renamed_fi +le ) ) ){ #add to zip } else{ print "$renamed_file is not a readable valid file id\n" }
    print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
      that was it EXACTLY...so simple but I wasn't seeing it. Thank you.
Re: problem with Archive::Zip
by almut (Canon) on Aug 09, 2010 at 12:01 UTC

    My guess would be that the $zip->addFile($renamed_file) failed and returned undef...  (so you're then trying to call desiredCompressionLevel(0) on this undefined value)

      This problem also wasted a day of my time, because I am a very occasional user of perl. I hope to save someone else the trouble.

      This line failed on Win32 with the error quoted above:

      $zip->addFile("$workPath\\shared\\base.dll", "$packageName/base.dll") or die "$! add file failed \n";

      The actual problem was the $workPath was wrong, making base.dll unavailable, but the 'or die' which I added to debug, didn't catch the missing file error. Frankly, once I followed the exact suggestion to use -e -r -f to check the filespec, the root cause was instantly revealed. The following revealed the error:

       if (( -f $$workPath\\shared\\base.dll) && ( -r $workPath\\shared\\base.dll)) { print "good\n";}else{ die " blah blah blah\n";}
Re: problem with Archive::Zip
by talexb (Chancellor) on Aug 09, 2010 at 18:28 UTC

    I'd recommend more defensive programming, as follows:

    my $zip = Archive::Zip->new() or croak "Failed to create a new archive"; $zip->addFile($renamed_file)->desiredCompressionLevel(0) or croak "Failed to add $renamed_file) to archive"; if( $zip->writeToFileNamed($zip_filename) != AZ_OK ) { croak "Failed to write to archive: $!"; } print "Added $renamed_file to $zip_filename\n";

    I've merely copied your use of $! in the last croak; I'm not sure if that ever gets populated by Archive::Zip.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re: problem with Archive::Zip
by Khen1950fx (Canon) on Aug 10, 2010 at 10:47 UTC
    I fixed a few mistakes. Here's what I came up with. Compare it to your script, and you'll see the mistakes.
    !/usr/bin/perl use strict; use warnings; use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); my $file1 = '/root/Desktop/abc.pl'; my $file2 = '/root/Desktop/dodah.zip'; my $zip = Archive::Zip->new(); my $file_member = $zip->addFile($file1, 'copy_log'); $file_member->desiredCompressionMethod( COMPRESSION_STORED ); unless ( $zip->writeToFileNamed($file2) == AZ_OK ) { die 'write error'; }