$ cat ./test.pl
#!/usr/bin/perl
use strict;
use warnings;
$\ = "\n";
opendir( my $dh, '.' ) or die;
while ( readdir $dh ) {
print;
};
$ ./test.pl
.
..
0
test.pl
Note the file named "0" in the test output.
Now let's use utf8::all module:
$ perl -Mutf8::all ./test.pl
Use of uninitialized value $_ in print at ./test.pl line 9.
Use of uninitialized value $_ in print at ./test.pl line 9.
Oops. There is no output at all, but two warnings that $_ is not defined. utf8::all replaces readdir with own implementation, _utf8_readdir, which is not a subject for Perl black magic: Perl does not assign the result of _utf8_readdir to the $_.
If I slightly rewrite the test to avoid using $_, the situation is even worse:
$ cat ./test.pl
#!/usr/bin/perl
use strict;
use warnings;
opendir( my $dh, '.' ) or die;
while ( my $entry = readdir $dh ) {
print "$entry\n";
};
$ ./test.pl
.
..
0
test.pl
$ perl -Mutf8::all ./test.pl
.
..
No warning, for the first look everything seems ok… but entry "0" and all entries after it are not printed. Silently.
The reason is the same: Perl black magic doesn't work with _utf8_readdir, and while loop checks condition for "trueness", not for "definedness", while "0" evaluates to false.
I have no idea whether it possible to fix the problem. But anyway, the utf8::all documentation should document this side effect in the section "CAVEATS".
Versions:
$ perl -v
This is perl 5, version 42, subversion 2 (v5.42.2) built for x86_64-linux-thread-multi
(with 15 registered patches, see perl -V for more detail)
Copyright 1987-2026, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.
$ perl -Mutf8::all -e 'print $utf8::all::VERSION, "\n";'
0.024
With the latest version 0.026 results are the same.
Note the file named "0" in the test output.
Now let's use
utf8::allmodule:Oops. There is no output at all, but two warnings that
$_is not defined.utf8::allreplacesreaddirwith own implementation,_utf8_readdir, which is not a subject for Perl black magic: Perl does not assign the result of_utf8_readdirto the$_.If I slightly rewrite the test to avoid using
$_, the situation is even worse:No warning, for the first look everything seems ok… but entry "0" and all entries after it are not printed. Silently.
The reason is the same: Perl black magic doesn't work with
_utf8_readdir, andwhileloop checks condition for "trueness", not for "definedness", while "0" evaluates to false.I have no idea whether it possible to fix the problem. But anyway, the
utf8::alldocumentation should document this side effect in the section "CAVEATS".Versions:
With the latest version 0.026 results are the same.