Why does Perl's glob return undef for every other call? Why does Perl's glob return undef for every other call? unix unix

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.