in reply to Re: Re: Re: Fileglob in scalar context question
in thread Fileglob in scalar context question

Because it makes sense. q-:

But seriously, although it makes some sense to have glob on a non-wildcard string turn into a substitute -e operator, there are quite a few reasons why the current behavior is convenient.

For example, if it didn't, you couldn't just write: @ARGV= map glob, @list; you'd have to write something like: @ARGV= map { my @g= glob; @g ? @g : $_ } @list; in order to process a list of file specs where you wanted to support wildcards.

You couldn't abuse glob for generating lists of related strings: @mispel= glob( "g{u,a,au,ua}r{r,}{a,u,e}nt{i,e,}{e,y}" );

You'd have to do double error reporting:

print "File(s): "; chomp( my $fileSpec= <STDIN> or exit(0) ); my @files= glob($fileSpec) # vvv or warn "No files matching $fileSpec found.\n"; # ^^^ This line not needed with current glob(). foreach my $file ( @files ) { if( ! open( FILE, "<$file" ) ) { warn "Can't read file, $file: $!\n"; next; } #...

Worse still, since the default glob allows multiple file specs separated by spaces, the above would really have to be:

print "File(s): "; my $fileSpec= <STDIN> or exit(0); my @files= map { glob($fileSpec) or (warn "No files matching $fileSpec found.\n")[()]; } split ' ', $fileSpec; foreach my $file ( @files ) { #...
in order to prevent "*.pl Makefile *.c" from just silently ignoring "Makefile" if that file didn't exist.

Though, on that last item, it is interesting to note that for the case of wildcards that don't match anything the behavior of csh's "glob" command were overridden by Perl such that an empty list is returned instead of the unexpanded original wildcard. This means that the above would silently ignore "*.pl" if there is nothing to match it. But then I think some people didn't like the way shell scripts end up trying to open a file named "*.pl" and complaining "can't open" instead of "no match".

It is a bit of a mixed blessing, but I think the advantages outweigh the disadvantages. Especial since the simple: grep -e, glob gives you the other behavior (though a bit less efficiently).

Then there is also the implementation-motivated explanation where the writer of glob has to find the wildcard characters then list all of the files and return only the ones that match. However, when you find there are no wildcard characters, why would you go through the work of listing all of the files to see if one matched exactly? So the "no wildcard" case ends up being a special case in the code. The whole rest of the code for glob never calls stat, so it feels a bit strange throwing in a call to stat for that one case.

Of course, it would be neat on case-ignoring file systems if glob("makefile") returned "Makefile" if that was the actual case of the matching file name. But that isn't currently the case. (:

Update: Yes, it is inconsistant.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Fileglob in scalar context question
by John M. Dlugosz (Monsignor) on Jul 01, 2001 at 05:59 UTC
    So if just feeding it a user-supplied filename, which may or may not contain wildcards, you don't want non-existing files to just disappear from the list. But with wildcards, no matches is no matches! Seems inconsistant. That is, I don't know why you would want
    @ARGV= map glob, @list;
    to work the way you say, unless you are also assuming that non-wildcard names are output files. I suppose the shell works this way because the whole line is passed through glob, and it doesn't know which items are supposed to be filenames or not. So as a point of design for that purpose, any string with no globbing characters are passed through unchanged.

    I can see the point about not reading a whole directory to see if one file exists. That's for OS's that don't have glob support on their directory listing primitive, I suppose.

    —John