SOLVED - Utterly BIZARRE behavior of IO::All vs glob

Discussion in 'Perl Misc' started by usenet@DavidFilmer.com, Dec 8, 2005.

  1. Guest

    Last Summer, when I was playing around with the IO::All module, I
    encountered a problem which I described in a usenet posting
    (http://tinyurl.com/8yvt8). I was having trouble using IO::All objects
    in other modules (this post described a problem with Digest::MD5).

    Tassilo responded, suggesting that there may be incompatibilities using
    IO::All with other modules. At the time, I accepted that, and worked
    around the problems using other coding techniques.

    I have since figured out what the problem is (and I now believe it is
    possible to easily use IO::All objects with ANY module). My main
    intention in posting this message is so that if someone searches Google
    Groups and finds the original post, hopefully s/he will also find this
    message which describes the problem/solution. THIS POST IS NOT
    INTENDED TO BE A QUESTION.

    Consider this code, which (should) simply add some .txt files to a
    zipfile:

    #!/usr/bin/perl
    use strict; use warnings;
    use IO::All;
    use Archive::Zip;

    my $zip = Archive::Zip -> new();

    foreach my $file (io('/tmp/test/')
    -> filter(sub {$_->name =~/.*\.txt/})
    -> all_files(1) ) {
    print "Adding file $file\n";
    $zip -> addFile($file);
    }
    $zip->writeToFileNamed( 'baz.zip' );

    __END__

    In the original post (a more complex test case), I described an error
    message. The above code won't produce any error messages (at least not
    on my system) but it won't add the .txt files to the zipfile either.

    The PROBLEM is that $file is not an "ordinary" scalar variable,
    although it acts like one in print statements (but not when passed to
    Archive::Zip). The nature of $file can be revealed using Data::Dumper:
    $VAR1 = bless( \*Symbol::GEN2, 'IO::All::File' );

    The SOLUTION is to "stringify" the variable/object ($file) when passing
    it to other modules. This is done simply by putting it in
    doublequotes. So the test script above will function as-intended by
    changing the addFile method thus:

    $zip -> addFile("$file");

    This behavior is well described in the perldoc for the module, under
    the OPERATOR OVERLOADING section:
    http://search.cpan.org/~ingy/IO-All-0.33/lib/IO/All.pod#OPERATOR_OVERLOADING
    When I encountered the problem originally, I didn't know enough to
    understand that this information addressed my problem.

    ===========================================
    ===========================================
    HERE IS THE TEXT OF THE ORIGINAL POST, WHICH I AM INCLUDING SO THAT
    GOOGLE WILL FIND THIS POST ALSO WHEN FINDING THE ORIGINAL
    ===========================================
    ===========================================

    (from 14 Jun 2005 in comp.lang.perl.misc, http://tinyurl.com/8yvt8):

    This is the most bizarre thing I have ever encountered. I was able
    (with some difficulty) to figure out what was going on, but I still
    don't know why.

    Consider this simple example script which looks for files and adds them
    to a zip archive:

    #!/usr/bin/perl -w
    use IO::All;
    use Archive::Zip;
    use Digest::MD5 qw/md5_hex/;
    use strict;

    my $zip = Archive::Zip -> new();
    my $dir = '/my/path';
    my $item = 'ETN599827';

    foreach my $file(sort glob ("$dir/$item*")) {
    print "PROCESSING: '$file' - @{[md5_hex $file]}\n";
    $zip -> addFile($file , io($file)->filename )
    || warn "Could not add $file\n";

    }

    THAT WORKS FINE. There is a debugging statement which prints the
    filename and the filename's md5sum, which outputs thus:

    PROCESSING: '/my/path/ETN599827.txt' - 0d8572577b458ded778efd0d88c6cf05

    But I prefer the flexibility IO::All, and lately I've been using that
    module exclusively for my IO needs.

    So what happens when I replace the glob with an IO::All statement
    (one-line change):

    foreach my $file (io($dir)-> filter(sub {$_->name =~
    /$item.*/})->all_files) {
    print "PROCESSING: '$file' - @{[md5_hex $file]}\n";
    $zip -> addFile($file , io($file)->filename )
    || warn "Could not add $file\n";

    }

    Perl outputs thus:

    &Digest::MD5::md5_hex function called with reference argument at
    test.pl line 29.
    PROCESSING: '/my/path/ETN599827.txt' - 0d8572577b458ded778efd0d88c6cf05
    stat() on unopened filehandle GEN535 at
    ..../site_perl/5.8.4/Archive/Zip.pm line 2503.
    Could not add /my/path/ETN599827.txt

    The Digest::MD5 and Archive::Zip messages are courtesy of "-w" - they
    don't print if warnings are not enabled.

    The IO::All function SEEMS to be returning a plain, ordinary scalar
    value whose MD5SUM is IDENTICAL to the result from the glob. This
    debugging statement is returning the identical result:
    print "PROCESSING: '$file' - @{[md5_hex $file]}\n";
    But Perl seems to think it's some type of reference when it comes
    from IO::All.

    This is Perl 5.8.4 built on AIX 5.1 using IO::All 0.33

    I'm very interested to learn more about what is happening. Does
    anyone have any ideas or suggestions? Thanks!

    ===========================================
    THIS IS THE (ONLY) REPLY BY Tassilo v. Parseval
    ===========================================

    My suspicion is that IO::All returns objects with overloaded
    stringification. Digest::MD5::md5_hex checks whether its argument is an
    object and, in case its not an instance of Digest::MD5, barfs.

    I am not really surprised that modules such as IO::All which
    incorporates every conceivable seemingly smart trickery would sooner or
    later exhibit strange interaction with other modules. That's the price
    you have to pay if you prefer laziness over robustness.

    Tassilo
    , Dec 8, 2005
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Georgy Pruss
    Replies:
    15
    Views:
    710
    Tim Roberts
    Dec 1, 2003
  2. Tim Peters
    Replies:
    1
    Views:
    345
    Duncan Booth
    Dec 1, 2003
  3. Sean Berry

    Question about glob.glob <--newbie

    Sean Berry, May 4, 2004, in forum: Python
    Replies:
    3
    Views:
    335
    David M. Cooke
    May 4, 2004
  4. Elbert Lev

    glob.glob unicode bug or feature

    Elbert Lev, Jul 31, 2004, in forum: Python
    Replies:
    5
    Views:
    377
    Neil Hodgson
    Aug 2, 2004
  5. Replies:
    1
    Views:
    175
    Tassilo v. Parseval
    Jun 14, 2005
Loading...

Share This Page