Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Perl's glob behaviour

by Anonymous Monk
on Nov 03, 2007 at 06:29 UTC ( #648772=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I don't understand the rationale for Perl's glob behaviour. Is this a bug or feature or both? :-)

$ ls x x* ls: x: No such file or directory ls: x*: No such file or directory ls: .x*: No such file or directory $ perl -v|head -n 2|tail -n1 This is perl, v5.8.8 built for i486-linux-gnu-thread-multi $ perl -le'print <x>' $ perl -le'print <x.>' x. $ perl -le'print <.x>' $ perl -e'print <x*>' $ ruby -v ruby 1.8.6 (2007-06-07 patchlevel 36) [i486-linux] $ ruby -e'p Dir["x"]' [] $ ruby -e'p Dir[".x"]' [] $ ruby -e'p Dir["x."]' [] $ ruby -e'p Dir["x*"]' []

Comment on Perl's glob behaviour
Download Code
Re: Perl's glob behaviour
by Anonymous Monk on Nov 03, 2007 at 06:31 UTC
    Sorry, <.x> also prints .x in Perl's case.
Re: Perl's glob behaviour
by Corion (Pope) on Nov 03, 2007 at 09:44 UTC

    The first case is different from the others. Using warnings helps there:

    $ perl -wle 'print <x>' Name "main::x" used only once: possible typo at -e line 1. readline() on unopened filehandle x at -e line 1.

    Using B::Deparse on the other three tells us that they use the same program structure:

    $ perl -MO=Deparse -le 'print <x*>' BEGIN { $/ = "\n"; $\ = "\n"; } use File::Glob (); print glob('x*'); -e syntax OK

    Using that snippet for your first case as well gives:

    $ perl -MFile::Glob -wle 'print glob "x"' x

    So glob treats the two first cases differently. The documentation says that it implements csh semantics. I guess that's why.

Re: Perl's glob behaviour
by tilly (Archbishop) on Nov 03, 2007 at 13:39 UTC
    Both. :-)

    It comes from shell glob expansion behaviour. That is what the shell does to the command line before it passes it on to the program. So if you have just listed some arguments, it will pass along those arguments. If you have listed some arguments with wildcards, it will expand those wildcards into a file list. And so on.

    It even has some features to make it easy to write things like this:

    cp some-long-filename{,.bak}
    (Fans of Perl golf sometimes find find the treatment of {} very useful.) This is very convenient in an interactive command-line environment. Shell scripters were also used to using this, and Perl just borrowed the same because Larry was trying to leverage existing knowledge.

    That said, if you don't come to Perl with this background, Perl's glob behaviour is very surprising. And can lead to lots of subtle bugs. Plus when I'm in defensive mode I don't trust programs that will do different (and surprising!) things depending on whether the file I'm looking for is there.

    So it's a feature. But surprises and can lead to bugs.

    Which is why in "real code" I tend to use opendir and readdir directly (possibly hidden behind a function).

    PS If you want behaviour closer to Ruby's, just grep for files:

    perl -e 'print grep -f, <x.>'
      Ah thanks for the clearing up. I do use Unix shell regularly for some years, but bash and never csh. So apparently they differ in wildcard expansion when it comes to non-matching wildcard containing ? or *.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2014-12-20 15:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (96 votes), past polls