Why does Perl's glob return undef for every other call?
glob
in scalar context:
In scalar context, glob iterates through such filename expansions, returning undef when the list is exhausted.
In
foreach (@list_env_vars){ print "$_ = ".glob()."\n";}
The glob()
there really is glob($_)
. Every iteration, $_
contains the string $SERVER
. Given that the environment variable does not change, $SERVER
is expanded to the same string. First time, this string is returned. Next, the list is exhausted, so undef
is returned. Third time, we start over. ...
Clarification: It does not matter that the argument to the second call is the same as the one for the first call since there is no way to reset glob
's iterator.
You can see this more clearly using the following example (current directory contains files '1.a', 1.b', '2.a' and '2.b'):
#!/usr/bin/perl -wuse strict;my @patterns = ( '*.a', '*.b',);for my $v ( @patterns ) { print "$v = ", scalar glob($v), "\n";}
Output:
C:\Temp> d*.a = 1.a*.b = 2.a
I would recommend accessing environment variables via the %ENV
hash:
my @list_env_vars = ($ENV{SERVER}) x 6;
or
my @list_env_vars = @ENV{qw(HOME TEMP SERVER)};
Incidentally, the reason why in 5.004 you get a variable expansion, while on 5.10 you just get your literal string back, is because on old perl, glob()
was carried out by the system shell, which just as a side-effect performs variable expansion. Since perl 5.6, glob()
uses the File::Glob
module which does the work itself, without the shell, and doesn't expand environment variables (which glob was never intended to do). %ENV
is the proper way to get at the environment.
Notes on the old behavior, wiki'd for your convenience (and so that I have the full range of markup and no 500-char limit):
The fact that glob
and <*globbything*>
changed in 5.6 is mentioned in passing in the docs (perl56delta
, perlop
, -f glob
) but the only real source on exactly how it used to work is a pre-5.6 version of perlop
. Here's the relevant bit from 5.005:
Example:
while (<*.c>) { chmod 0644, $_;}
is equivalent to
open(FOO, "echo *.c | tr -s ' \t\r\f' '\\012\\012\\012\\012'|");while (<FOO>) { chop; chmod 0644, $_;}
In fact, it's currently implemented that way. (Which means it will not work on filenames with spaces in them unless you have csh(1) on your machine.)
Heh, that's pretty evil stuff. Anyway, if you ever find yourself wanting to consult old perldocs like that, just go to search.cpan.org, pull up the perl
distribution, use the pulldown list to select an old version, then click through to the doc that you need. perl
itself isn't really subject to getting "tidied" off of CPAN; currently everything from 5.004 on up is available without hitting BackPan.