Actually, it returns "test.txt" even if the file doesn't exist.
-
tye
(but my friends call me "Tye")
| [reply] |
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") | [reply] [d/l] [select] |
John,
While you are probably right about being confused about "the
stuff between the angles", the original program did have a
wild card in it. In the first pass through the loop, it would
look like </home/scott/manydirs/0/*test.txt>.
However, on thinking about this problem more, I think I would
rewrite the code to look like this:
#!/usr/bin/perl -w
use strict;
my @EXON_IN = </home/scott/manydirs/[0-9]*/*test.txt>;
foreach my $file (@EXON_IN){
#do whatever it was my coworker wanted to do
#Greg, are you looking?
}
Which is probably what I would have done if I was doing this
from scratch, but when presented with another's code, it is
often hard to think of the "right" thing to do right away.
Thanks,
Scott | [reply] [d/l] [select] |