Let's try a little something different.
First off, there's a nice syntax using the -> for referenced arrays and hashes. Here I am going to make a array of people. I'll make a hash of %person that contains all that person's information:
my %person;
my $person{NAME} = "Bob";
my $person{JOB} = "Programmer";
my $person{PHONE} = "555-1234";
Now, I'll put it into an array:
my @array
my $array[0] = \%person;
I could reference the person in the array this way:
print ${$array[0]}{NAME} . "\n"; #Prints Bob
print ${$array[0]}{JOB} . "\n"; #Prints Porgrammer
But, Perl gives me a nice clean way to do this:
print $array[0]->{NAME} . "\n"; #Prints Bob
print $array[0]->{JOB} . "\n"; #Prints Progammer
In fact, I could skip the hash all together. Here I am adding Jill to my array:
$array[1]->{NAME} = "Jill";
$array[1]->{JOB} = "DBA";
$array[1]->{PHONE} = "555-5555";
You can see this is a much simpler way to use references. It's easier to see what is going on and takes fewer lines of code.
You can refer to an array of an array like this:
$myarray[1]->[3] = 42;
Or have a hash which stores an array. In this day and age, who has only a single phone number?:
$person[1]->{PHONE}->[0] = "555-4567";
$person[1]->{PHONE}->[1] = "555-4444";
Or, to make it even more complex we could have a hash of a hash of an array:
$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";
Using this syntax will really help clean up a lot of your code. You won't have to store the information into individual structures that are then only used to make references. Instead, you can simple setup your structure the way you want without intermediary steps.
Now to your problem: You're trying to store a bunch of information about files into a series of arrays. What you're hoping is that $array_mode[1] goes with $array_file[1] and you have to keep all of these arrays in sync. This is a pain and it is complex.
The entire purpose of using references is to eliminate this need for multiple variables. If you're going to use references, why not simply store your entire file structure into a single array.
What you really, really want is an array of hash references. And, that hash reference will be keyed based upon your file attributes. Here is your code restructured into using an array of hash references. I didn't even bother to check the rest of it. For example, I'm not sure how your localtime thing will work:
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
}
That's way shorter and cleaner. Plus, you know that $files[0]->{NAME} goes with $files[1]->{SIZE}, and if you remove $files[0] from your array, or transfer it to another variable, all of the attributes of that file go together.
Here's how you'd print it out:
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};
}
Simple and easy to do.
However, I would argue what you really want is a hash of hashes. Let your file name be the key to your main hash, and let {SIZE}, {LAST_MOD}, and {RET_MODE} be the keys to your sub hash:
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?
}
Now if someone asks, "When was foo.txt last modified?", you can say:
say "File 'foo.txt' was last modified on " . $file{foo.txt}->{LAST_MOD};
And to print out your entire structure:
for my $file_name ( sort keys %files ) {
say "File: $file_name";
for my attribute ( sort keys %{ $file_name } ) {
say " $attribute: " . $files{$file_name}->{$attribute};
}
}
Next step is to learn about Object Oriented Perl! Object Oriented Perl uses these types of references, but will greatly simplify the handling of these references, so you make fewer programming mistakes.