让我们尝试一些不同的东西。
->
首先,使用for 引用数组和散列有一个很好的语法。在这里,我将制作一组人。我将对其进行哈希处理%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]
必须使所有这些阵列保持同步。这是一种痛苦,而且很复杂。
使用引用的全部目的是消除对多个变量的需求。如果您要使用引用,为什么不简单地将整个文件结构存储到一个数组中。
你真正想要的是一个哈希引用数组。并且,该哈希引用将根据您的文件属性进行键入。这是您的代码重组为使用哈希引用数组。我什至没有费心去检查它的其余部分。例如,我不确定您的 localtime 将如何工作:
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};
}
简单易做。
但是,我认为您真正想要的是hashes的散列。让您的文件名成为您的主散列的键,并让、和成为您的子散列的键:{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};
}
}
下一步是学习面向对象的 Perl!面向对象的 Perl 使用这些类型的引用,但会大大简化对这些引用的处理,从而减少编程错误。