1

When I open a directory with opendir() and later call readdir() two times in a row, the latter returns an empty array.


minimal_example.pl:

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper qw(Dumper);

opendir(my $DIRH, "/home") or die "Cannot open /home: $!\n";

my @FILES  = readdir($DIRH);
my @FILES2 = readdir($DIRH);

print Dumper \@FILES;
print Dumper \@FILES2;

output:

$VAR1 = [
          '.',
          '..',
          'users',
          'sysadmin',
          'ne'
        ];
$VAR1 = [];

Is that expected behavior?

noah
  • 312
  • 2
  • 13

2 Answers2

2

Many operators in Perl return differently based on whether they are called in list or scalar context. This is the case with readdir

Returns the next directory entry for a directory opened by opendir. If used in list context, returns all the rest of the entries in the directory. If there are no more entries, returns the undefined value in scalar context and the empty list in list context.

Since the return of readdir in your code is assigned to an array it is in list context so it reads all that there is in that directory. Thus, as the directory handle got to the end of the filelist, the next "read" returns an empty list (even if more files were added in the meanwhile).

I don't see what is expected from reading a list of files twice, but to process a directory multiple times one can use rewinddir.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • Thank you! I don't see why anybody would use that either, but it's part of an old code im testing at the moment, and somehow it was like this for years without anyone noticing. – noah Oct 19 '22 at 16:26
  • @noah Hah! Interesting. A related, and perhaps sensible, use may be to repeatedly check a directory that is changing. (But then one needs to `rewinddir` or re-enter scope, like `while (...) { opendir my $dh ... }`) – zdim Oct 19 '22 at 16:31
1

Yes, this is the expected behavior. Your first call to readdir() read the entire directory and assigned its contents to @FILES. This left nothing for the second readdir() to read, so it returned nothing.

Jim Davis
  • 5,241
  • 1
  • 26
  • 22
TomW
  • 11
  • 1
  • Thank you! Do you have any sources with a deeper explanation of that? – noah Oct 19 '22 at 14:50
  • @noah - Added link to `readdir` docs. From the first paragraph: _"If used in list context, returns all the rest of the entries in the directory. If there are no more entries, returns the undefined value in scalar context and the empty list in list context."_ – Jim Davis Oct 19 '22 at 15:40