Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

i have a list of files that i'd like to put into an array. there are a number of different files each indentified by a 2 letter prefix. so the files might be call vs010101.000, ud010101.000, eq010101.000. at any other time there might a another type added. what i'd like to do is push modification times of each of those files into arrays for each type.

so i might have

for (@filetypes) { push(@$_modtime,$modtime); #obviously not how its done }

or something like that. what i'd like to know if how i create an array like that where the first 2 characters of the array are the type of file it is.

thanx in advance

Replies are listed 'Best First'.
Re: dynamically named arrays
by BrowserUk (Patriarch) on Oct 21, 2002 at 04:53 UTC

    Rather than trying to create dynamically named arrays (which can be done but requires using things called symbolic references which are generally frowned upon unless there is a specific reason for their use) a hash of arrays seems like your best option here.

    Some sample code to get you started. See perldata and perlreftut for further info.

    #! perl -sw use strict; my %files; while(<DATA>) { chomp; my ($type, $ts) = m/(..)(.*)/; $files{$type} = [] if not exists $files{$type}; push @{$files{$type}}, $ts; } foreach my $type (keys %files) { print $type,$_,$/ for sort @{$files{$type}}; } __DATA__ vs010101.000 ud010101.000 ve020202.000 eq131302.000 eq010101.000 vs031102.000 us020101.000 ve051001.000

    Gives output

    c:\test>206767 eq010101.000 eq131302.000 us020101.000 ud010101.000 vs010101.000 vs031102.000 ve020202.000 ve051001.000 c:\test>

    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!

      thanks for all the replies! whats basically happeneing is that someone at work is writing a catalogue search program in clarion (i know, i'd write it in perl if it were feasible) and becuase of clarion's lack of networking support i was asked to write a program to download catalogue updates. i came up with the ingenious idea of downloading updates of each type, getting the modification time for each file downloaded and put it into an array (intrinsicly named after the type). after all files have been downloaded it would sort the array, get that latest modified file and put it into an ini file so next time the update program is run it will check the modification time of the file its downloading against the one in the ini file. probably not the best way to do things but i can't think of any other way at the moment - i'm sure that will change.

        If the box on the other end is a UN*X box you could consider touching a file in each directory holding files called something like '.browser-time'.

        If the timestamps of the '.browser-time' and the '.' differ, files where changed or added since your last visit, cause the '.' takes over the timestamp of the latest changed or added file

        This can save you some time in searching these things.

        er formait hyarya.
        -- "Life is a house and the next tornado is never far away"
        -- "lovely by nature"

        You may find that a DB_File or relative would be more suitable than an INI file.

        --- demerphq
        my friends call me, usually because I'm late....

Re: dynamically named arrays
by graff (Chancellor) on Oct 21, 2002 at 04:40 UTC
    It looks like the OP doesn't need to keep track of the individual file names, so although a hash of hashes seems like a natural thing to do, I think a hash of arrays is all that was requested. (And it looks like sch's reply is meant for Perl6 -- those of us still using Perl5 would say $filedate{...}).

    Anyway, here's an approach that does what the OP proposed:

    push( @{$modtimes{substr($filename,0,2)}, $modtime );
    Then it's easy to get the arrays back, one type at a time:
    foreach $type ( sort keys %modtimes ) { @times = @{$modtimes{$type}}; # do something with this set of @times... }

      Indeed, in the original question it doesn't specify that the filename should be stored - just seemed to me that if you were storing the file modification times you might want to know which file they referred to :)

      BTW, thanks for the pointer on the

      $filedata{...}
      got my $ and % mixed up there for a mo.

      But today you took me walking, Through a land that we have lost,
      While our children sit at websites, With no access to the cost

Re: dynamically named arrays
by sch (Pilgrim) on Oct 21, 2002 at 04:03 UTC

    I'm only starting out on this stuff, but it sounds to me like you're looking for a Hash of Hashes where the key of the first level of hashes is the filetype, the key of the second level would be the filename and the value would be the modification time.

    I'm not sure if it's possible but I'd guess it'd be initialised something like:

    %filedata{substr($filename, 0,2)} = { %{$filename} = $mod_time };

    Updated: I checked How do I make a hash of hashes? and it looks like the initialization should be something like:

    %filedate{substr($filename, 0, 2)} = { $filename => $mod_time };

    But today you took me walking, Through a land that we have lost,
    While our children sit at websites, With no access to the cost

Re: dynamically named arrays
by diotalevi (Canon) on Oct 21, 2002 at 04:09 UTC

    The easiest thing to do is symbolic references. Here's a sample implementation. I can understand wanting to just say: "push $modtime onto each of the arrays named 'vs', 'ud', 'eq' etc" but I'm not sure what the deal is with naming the array with the modtime. Oh well - it's your data. It sounds like a bad idea to me but then I'm not you. If you use this be sure to keep that "no strict 'refs'" local to that one block - normally this feature is something you only use by the time you know not to use it. It's just an even easier way to write buggy code. etc, etc. Consider yourself (vaguely) warned.

    for (@filetypes) { no strict 'refs'; # See [perlref] regarding "Symbolic references". push @$_, $modtime; }
    __SIG__ printf "You are here %08x\n", unpack "L!", unpack "P4", pack "L!", B::svref_2object(sub{})->OUTSIDE;