讓我們嘗試一些不同的東西。
首先,使用->
作爲參考數組和散列使用了很好的語法。在這裏,我要製作一批人。我會做的%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) –