让我们尝试一些不同的东西。
首先,使用->
作为参考数组和散列使用了很好的语法。在这里,我要制作一批人。我会做的%person
哈希包含所有的人的信息:现在
my %person;
my $person{NAME} = "Bob";
my $person{JOB} = "Programmer";
my $person{PHONE} = "555-1234";
,我就会把它变成一个数组:
my @array
my $array[0] = \%person;
我可以引用人阵这种方式:
print ${$array[0]}{NAME} . "\n"; #Prints Bob
print ${$array[0]}{JOB} . "\n"; #Prints Porgrammer
但是,Perl中给了我一个很好的清洁方法来做到这一点:
print $array[0]->{NAME} . "\n"; #Prints Bob
print $array[0]->{JOB} . "\n"; #Prints Progammer
事实上,我可以一起跳过散列。在这里,我将Jill添加到我的阵列中:
$array[1]->{NAME} = "Jill";
$array[1]->{JOB} = "DBA";
$array[1]->{PHONE} = "555-5555";
您可以看到,这是一种使用引用的简单方法。更容易看到发生了什么并且需要更少的代码行。
你可以参考一个数组的数组是这样的:
$myarray[1]->[3] = 42;
或有存储数组中的哈希。在这个时代,谁拥有只有一个电话号码?:
$person[1]->{PHONE}->[0] = "555-4567";
$person[1]->{PHONE}->[1] = "555-4444";
或者,使它更加复杂,我们可以有一个数组的哈希散列:
$person[1]->{PHONE}->{CELL}->[0] = "555-1111";
$person[1]->{PHONE}->{CELL}->[1] = "555-2222";
$person[1]->{PHONE}->{HOME}->[0] = "555-3333";
$person[1]->{PHONE}->{JOB}->[0] = "555-4444";
$person[1]->{PHONE}->{JOB}->[1] = "555-5555";
使用这个语法将真正帮助清理大量的代码。您不必将信息存储到仅用于进行引用的单个结构中。相反,您可以按照自己想要的方式简单设置结构,而无需中间步骤。
我们您的问题:你试图将有关文件的大量信息存储到一个系列阵列。你所希望的是$array_mode[1]
与$array_file[1]
一起,你必须保持所有这些阵列同步。这是一个痛苦,它很复杂。
使用引用的全部目的是消除对多个变量的这种需要。如果你要使用引用,为什么不把你的整个文件结构存储到一个单一的数组中。
你真正想要的是一个哈希引用数组。并且,该哈希引用将基于您的文件属性进行键控。这里是你的代码重构成使用哈希引用数组。我甚至懒得去检查其余部分。例如,我不知道你的本地时间的事情将如何工作:
use strict;
use warnings;
use feature qw(say);
use File::stat;
my @files;
for my $file (@ARGV) {
my $info = stat($file);
my $file = {}; #This will be a reference to a hash
$file->{NAME} = $file;
$file->{SIZE} = $info->size;
$file->{RET_MODE} = $info->mode & 0777;
$file->{LAST_MOD} = localtime $info->mtime; #Does this work?
push @files, $file #Pushes the hash reference onto the array
}
这是更短,更干净。另外,您知道$files[0]->{NAME}
与$files[1]->{SIZE}
一起使用,并且如果您从数组中删除$files[0]
,或者将其转移到另一个变量,则该文件的所有属性都会合并在一起。
这里是你如何把它打印出来:
for my $file (@files) {
say "File Name: " . $file->{NAME};
say "File Size: " . $file->{SIZE};
say "Last Modified: " . $file->{LAST_MOD};
say "File Mode: " . $file->{RET_MODE};
}
简单易做。
不过,我认为你真正想要的是散列一个哈希。让你的文件名是关键,你的主要哈希,让{SIZE}
,{LAST_MOD}
和{RET_MODE}
是关键的子散:
my %files = {}; #This is a hash of hashes
for my $file_name (@ARGV) {
my $info = stat($file);
$files{$file_name}->{SIZE} = $info->size;
$files{$file_name}->{RET_MODE} = $info->mode & 0777;
$files{$file_name}->{LAST_MOD} = localtime $info->mtime; #Does this work?
}
现在,如果有人问,“当被foo.txt
最后修改? “,你可以说:
say "File 'foo.txt' was last modified on " . $file{foo.txt}->{LAST_MOD};
,并打印出你的整个结构:
for my $file_name (sort keys %files) {
say "File: $file_name";
for my attribute (sort keys %{ $file_name }) {
say " $attribute: " . $files{$file_name}->{$attribute};
}
}
下一步是了解Object Oriented Perl!面向对象的Perl使用这些类型的引用,但会大大简化对这些引用的处理,所以你减少了编程错误。
查看perlLOL - [perl列表中的列表]的官方文档(http://perldoc.perl.org/perllol.html) –