A: 

(Scratching away at my rusty memory of Perl...) I think that multiple lexical instances of <*> are treated as independent invokations of glob, whereas in the while loop you are invoking the same "instance" (whatever that means).

Imagine, for instance, if you did this:

while (<*>) { ... }
...
while (<*>) { ... }

You certainly wouldn't expect those two invocations to interfere with each other.

Marcelo Cantos
They wouldn't interfere because the first invocation would reset after returning undef, according to the documentation.
Rob
I would expect separate instances in different scopes, but in the same scope I would expect to invoke the same "instance".
Rob
What if there's a conditional `break' in the middle of the first one? At the end of the day, what the Perl interpreter actually does is the "truth".
Marcelo Cantos
Outside of a loop, is there a way to call the first "instance" again?
Rob
Sorry @Rob, you're outside my sphere of knowledge now.
Marcelo Cantos
@Rob, no, it's a thing in the optree, not an "object" in the normal perl sense. There's no practical way to get at it. I think I know a way to reify it though -- answer forthcoming :)
hobbs
+3  A: 

Also from perlop:

A (file)glob evaluates its (embedded) argument only when it is starting a new list.

Calling glob creates a list, which is either returned whole (in list context) or retrieved one element at a time (in scalar context). But each call to glob creates a separate list.

mobrule
+4  A: 

The following code also seems to create 2 separate instances of the iterator...

for ( 1..3 )
{
   $filename = <*>;
   print "$filename\n" if defined $filename;
   $filename = <*>;
   print "$filename\n" if defined $filename;
}

I guess I see the logic there, but it is kind of counter intuitive and contradictory to the documentation. The docs don't mention anything about having to be in a loop for the iteration to work.

Rob
+1 Great experiment. This is similar to how the range operator (`..`) behaves, where each use of the operator maintains its own state. Heck if I can find that documented anywhere, though.
mobrule
+5  A: 

Here's a way to capture the magic of the <> glob operator's state into an object that you can manipulate in a normal sort of way: anonymous subs (and/or closures)!

sub all_files {
    return sub { scalar <*> };
}

my $iter = all_files();
print $iter->(), "\n";
print $iter->(), "\n";
print $iter->(), "\n";

or perhaps:

sub dir_iterator {
    my $dir = shift;
    return sub { scalar glob("$dir/*") };
}
my $iter = dir_iterator("/etc");
print $iter->(), "\n";
print $iter->(), "\n";
print $iter->(), "\n";

Then again my inclination is to file this under "curiosity". Ignore this particular oddity of glob() / <> and use opendir/readdir, IO::All/readdir, or File::Glob instead :)

hobbs
Interesting method and good workaround for capturing the state of the operator. I was wondering how/if that could be done.
Rob