Creating a hash in Perl
How do I create a hash in Perl which uses the directory name as the key, and then stores both the count of files in the director开发者_如何学编程y as well as the names each of the files? Is it possible using hash of hashes or hash of arrays?
I would appreciate any pointers.
Hash values must be scalars, so the real question is how to get two values into one scalar. References are scalars, so a reference to a hash would work.
$data{$dir} = {
file_count => 0+@files,
files => \@files,
};
Note that the file count is redundant. 0+@{ $data{$dir}{files} }
could be used for the file count. If you choose to get rid of this redundancy, you could use
$files{$dir} = \@files;
The file count is available as
0+@{ $files{$dir} }
and the files are available as
@{ $files{$dir} }
(The 0+
can be omitted in scalar context.)
If I understand you correctly, this seems to do the trick (the printing of the hash using Dumper() at the end is just to show you what the hashref contains):
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $dir = $ENV{PWD};
opendir( DIR, $dir ) or die $!;
my @files = grep { -f "$dir/$_" } readdir( DIR );
my $hash = {
$dir => {
count => scalar( @files ),
files => \@files,
}
};
print Dumper( $hash ), "\n";
Personally almost always I use hash references instead perl hashes (and arrayrefs instead perl arrays, too). Example:
my $dirs = {
'/home/user' => [ '.profile', '.bashrc', 'My_pic.png' ],
'/root' => [ '.profile', '.zshrc' ]
};
my $var = { (...) }
makes hash reference, =>
is just a synonym of comma ,
but allows distinguishing between hash keys and values. [ (...) ]
makes annonymous array reference which is assigned as hash value.
You don't have to store redundant information like number of files, you can just evaluate array in scalar context:
my $root_files = $dirs->{'/root'};
$size = scalar @{$root_files};
You can read more about hashes here and here.
精彩评论