http://qs1969.pair.com?node_id=242007


in reply to Passing Array of Arrays

First thought on reading this is "wow, you're doing a lot that you don't have to." There are a few stylistic issues that boil down to making your code a little more readable. But a big thing might be to forego the idea of using an array of arrays. You're dealing with filenames, which, in a given directory, must be unique. You want to record a certain bit of information about each file, so why not have the keys be the filenames and the values be those bits of information?

For example, to get the mtimes on all your files, which is the only bit from the stat call you want to keep, you can do the following:

my %filenames =(); foreach( <post*.*> ) { $filenames{$_} = -M $_; }
This uses the -M filetest operator (see perldoc -f -X on your system for more info on the filetest operators) instead of that long stat call and is more mnemonic than using, say, a list slice on the stat call. ( as an aside you can ignore for the moment, you could compress to a single line with my %filenames = map { $_ => -M $_ } <post*.*>; this does pretty much the same thing as the foreach loop, but is shorter). Anyhow, with a hash, you would sort it by the mod time via something like the following:
my @sorted_keys = sort { $filenames{$a} <=> $filenames{$b}} keys %file +names;
(you don't need to name the array, but I just wanted to illustrate how you get the set of keys of the filename hash sorted according to values).

Now, for your original question (finally!). I think what's going on is a scoping issue. You define @fileanddate outside the loop, and put a reference to it into the array you're returning each time you process a file. But there is only one @fileanddate, so you're filling up your returned array with a bunch of references to that same thing. A better approach, keeping your current code for the most part, would have your loop that constructs the array look like this:

foreach my $filename ( @filenames ) { # create an ANONYMOUS array (basically a reference to an array) my $record = [ $filename, -M $filename ]; push @filesanddates, $record; }
This ought to do what you want with much less fuss. An absolutely minimal fix would just move the declaration of @fileanddate into the subroutine (update NO! array building loop ... ooops. ), so you get a "fresh" lexically-scoped variable on each iteration through the loop.

HTH!

If not P, what? Q maybe?
"Sidney Morgenbesser"