Skip to content

Commit 87fe274

Browse files
committed
File::stat: document/test stat \*_ syntax to reuse stat buffer
I'm not sure why the "unexported and undocumented populate() function" had to be mentioned here. The more straightforward `stat(\*_)` syntax works on all perl versions back to (at least) 5.8.9 and is compatible with CORE::stat, too.
1 parent 5c3a736 commit 87fe274

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

lib/File/stat.pm

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,19 @@ built-in C<stat>/C<lstat> functions):
310310
311311
=head1 BUGS
312312
313-
As of Perl 5.8.0 after using this module you cannot use the special
314-
filehandle C<_> with stat() or lstat(); trying to do so leads to strange
315-
errors. The workaround is to explicitly populate the object using the
316-
unexported and undocumented populate() function with CORE::stat():
313+
The built-in C<stat> and C<lstat> functions recognize the special
314+
filehandle C<_> (underscore) to indicate that no actual C<stat> be done;
315+
instead the results of the last C<stat> or C<lstat> or filetest operation
316+
should be returned. This syntax does not work with File::stat, but the
317+
same result can be achieved by passing C<stat> a reference to the C<*_>
318+
typeglob:
319+
320+
use File::stat;
321+
my $stat_obj = stat \*_; # reuse results of last stat operation
322+
323+
Alternatively, another workaround is to explicitly populate the object
324+
using the unexported and undocumented populate() function with
325+
CORE::stat():
317326
318327
my $stat_obj = File::stat::populate(CORE::stat(_));
319328

lib/File/stat.t

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,17 @@ SKIP:
240240
{
241241
# implicit $_
242242
$_ = $file;
243-
isa_ok stat, 'File::stat', 'stat()';
243+
my $st_1 = stat;
244+
isa_ok $st_1, 'File::stat', 'stat()';
245+
246+
# reuse stat buffer
247+
my $st_2 = stat \*_;
248+
isa_ok $st_2, 'File::stat', 'stat(\\*_)';
249+
# we can't verify directly that no actual stat() was done, but we can check
250+
# that the returned device/inode match those of $file even though *_{IO}
251+
# (the actual _ handle) was never opened
252+
is $st_1->dev, $st_2->dev, 'stat(\\*_)->dev matches that of last stat()';
253+
is $st_1->ino, $st_2->ino, 'stat(\\*_)->ino matches that of last stat()';
244254
}
245255

246256
# Testing pretty much anything else is unportable.

0 commit comments

Comments
 (0)