Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Portability of glob function in a modern perl

by ccn (Vicar)
on Aug 12, 2005 at 07:56 UTC ( [id://483202]=perlquestion: print w/replies, xml ) Need Help??

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

perl-5.004_04 documentation states:
glob EXPR glob Returns the value of EXPR with filename expansions such as a shell would do. This is the internal function implementing the <*.c> operator, but you can use it directly. If EXPR is omitted, $_ is used. The <*.c> operator is discussed in more detail in I/O Operators.
perl 5.8.7 documentation states:
# glob EXPR # glob In list context, returns a (possibly empty) list of filename expansions on the value of EXPR such as the standard Unix shell /bin/csh would do. In scalar context, glob iterates through such filename expansions, returning undef when the list is exhausted. This is the internal function implementing the <*.c> operator, but you can use it directly. If EXPR is omitted, $_ is used. The <*.c> operator is discussed in more detail in "I/O Operators" in perlop.

I highlighted with bold the changes what I am interested for.

Do those changes mean that glob became portable?

Replies are listed 'Best First'.
Re: Portability of glob function in a modern perl
by Corion (Patriarch) on Aug 12, 2005 at 07:59 UTC

    It became "portable" in the sense that it behaves in its broken way everywhere, regardless of what shell is installed now, because the functionality was moved into Perl.

    It is quite common for Perl scripts using glob to break on Win32 because the author could not imagine that whitespace is a thing that happens in filenames and directories. So for anything but trivial hacks, File::Find or File::Find::Rule are to be preferred over glob.

      I don't see the problem with glob and whitespace in filenames. As long as the user understands that glob uses csh rules and escapes whitespace appropriately, it works the same in Windows and in Unix.

      Added: Thanks for the examples, now I see what you mean (I've made the same mistakes in the past!).

        A quick search through CPAN (provided by http://cpansearch.bulknews.net/) provides me with following ugly usages of glob that will not work for quoted spaces in the path, as the path is otherwise used for directly constructed filenames too:

        Mac::iPod::GNUPod

        ... my $path = File::Spec->catdir($self->{mnt}, @path); ... # and $self->add_song(glob(File::Spec->catpath($self->{mnt}, "iPod_Control +", "Music", "*", "*")));

        ($self->{mnt} is supposed to be the mount point of the iPod)

        Mail::Action::Role::Purge

        my $dir = $self->storage_dir; ... my @files = map { scalar( s/\.$extension//, basename $_) } glob("$dir/*.$extension");

        ($self->storage_dir is supposed to be the directory for storage, unquoted)

        CDDB::Fake

        ... foreach my $dir ( @ARGV ) { unless ( -d $dir ) { warn("$dir: not a directory -- skipped\n"); next; } ... my @files = sort map { $1 if /([^\/]+)\.mp3$/ } glob("$dir/[0-9]*.mp +3");

        Same as above

        I stopped here, on page three of the results (when searching for glob).In short, a directory and it's glob-safe quoted string are not usable interchangeably, and thus will lead to problems with the authors that can't imagine/foresee whitespace in filenames.

        As an aside, the cpansearch doesn't seem to like searching for "glob(", which would exclude a lot of "typeglob" results.

      Does using File::Glob::bsd_glob() instead solve the spaces issue? Or are there other traps?

        No - for the cases where I use glob, I always have use File::Glob qw(bsd_glob); at the top of my script. When using glob, bsd_glob is the sane and safe way.

Re: Portability of glob function in a modern perl
by ambrus (Abbot) on Aug 12, 2005 at 08:36 UTC

    perlop of perl 5.004_05 specifically mentions that it calls csh.

    Thus, the difference is not what kind of shell is concerned, but the fact that newer perls do not call the shell, just emulate it, while older perls really call it.

      I wonder how the perl can call csh on Windows? I thought that oldest perls just call default shell for the platform where they are running. The older perls emulate default shell. Modern perl emulates standard csh.

        Read the section about glob in the perldoc perlport of older perl versions if you are interested in these details.

Re: Portability of glob function in a modern perl
by Anonymous Monk on Aug 12, 2005 at 08:47 UTC
    What does perlport say?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://483202]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-19 03:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found