New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Undocumented weird CORE::glob() behavior #14321
Comments
From @kbensonThis is a bug report for perl from kentrak@gmail.com, This was spurred from a discussion on Hacker News, and I think my reply You picked an extremely good built-in as an example. It doesn't function exactly as you've shown it, but there is very weird stuff going on. On the plus side, this is the only time I've seen something quite like this in Perl, so I'm not sure it's represents the state of using Perl as a whole very well. glob appears to do something special, and unlike most other Perl functions where it's just a matter of knowing the context and the API the function exposes. In the versions I just tested (including 5.21.6), glob in fact doesn't quite do what it's documentation says, in the apparent effort to "do what you mean". It does not iterate through files in the result when used in scalar context, it iterates through files in the result when used in scalar context and in the exact same call-site in the program. Here's all the files we'll test # perl -E 'my @files = glob("*"); say for @files; Glob acts like an iterator when used in scalar context. Here, each call # perl -E 'while ( my $file = glob("*") ) { say $file; } ' Glob gives the first file each time it's called in scalar context if it's # perl -E 'my $file1 = glob("*"); my $file2 = glob("*"); say $file1; say $file2;' Again, we see it's not acting like an iterator. Each call is generating # perl -E 'my $file1 = glob("*"); my $file2 = glob("two*"); say $file1; say $file2;' Here, we can see that since the same point in the code is getting hit, glob # perl -E 'sub myglob { my $mask = shift; glob($mask); } my $file1 = myglob("*"); my $file2 = myglob("*"); say $file1; say $file2;' Here we see that since the same point in code is getting hit, glob is # perl -E 'sub myglob { my $mask = shift; glob($mask); } my $file1 = myglob("*"); my $file2 = myglob("two*"); say $file1; say $file2;' That is very weird behavior. I agree it's not consistent with the rest # perl -E 'use File::Glob qw/:bsd_glob/; my $file1 = bsd_glob("*"); my $file2 = bsd_glob("two*"); say $file1; say $file2;' Of course, this means the documentation that says the core glob routine is So, congratulations, you picked an extremely good example and unearthed some Note: that bsd_glob seems to return the last item when used in scalar context, [1]: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=2707 [2]: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=2713 Flags: Site configuration information for perl 5.21.6: Configured by root at Thu Dec 4 11:38:18 PST 2014. Summary of my perl5 (revision 5 version 21 subversion 6) configuration: @INC for perl 5.21.6: Environment for perl 5.21.6: |
From @cpansproutOn Wed Dec 10 11:31:29 2014, kentrak@gmail.com wrote:
This call-site behaviour has always been present for glob. I wouldn’t consider it a bug. But the documentation is somewhat lacking.
It is an iterator, but it’s a different iterator for each call site. Honestly, I don’t see how else a glob iterator could behave.
That pretty much explains it all.
File::Glob was poorly implemented when it was first dragged kicking and screaming into the core in 5.6. Just thinking about it makes my head hurt. :-( It would take me a long time to explain all the foibles. -- Father Chrysostomos |
The RT System itself - Status changed from 'new' to 'open' |
From @kbensonYeah, I understand "fixing" the behavior of this is a non-starter at this |
Migrated from rt.perl.org#123404 (status was 'open')
Searchable as RT123404$
The text was updated successfully, but these errors were encountered: