"Kent, Mr. John" wrote:

> Greetings,
>
> Am using perl to dynamically write some JavaScript code
> that creates cool drop down button menus by Ger Versluis found
> on http://www.dynamicdrive.com  ( for those who want to
> know why).
>
> Have a directory structure in which the target files are located
> at various levels of sub-directories.
>
> Trying to create a dynamically sized hash of unknown dimensions
> where each sub directory name is a dimension of the hash and it
> gets assigned the file.

Please read the documentation on hashes before making assumptions about how they look. 
 There are ways to use a string as a
variable name, but that is a very advanced issue.  There are almost always better ways 
to do things

>
>
> For example
> my(%HASH);
> $HASH{$sub1}{$sub2}{$sub3} = $file1;
> $HASH{$sub1}{$sub2}{$sub3}{$sub4}{$sub5} = $file2;

Nope.  Hashes cannot be contained inside other structures.
The constructors for both arrays and hashes use lists of scalars.  When you put a hash 
or array directly into another
structure, you "flatten" it tpo a list of scalars, squeezing the magic out of it in 
the process:

   *******************

Greetings! E:\d_drive\ocf\discuss\prototype>perl -w
my %ordianl_hash = (first => 1, second => 2, third => 3);
my @array = (5, 6, %ordianl_hash, 34, 'Jack Sprat');
print "$_, " foreach @array;
print "\b\b  \n\n";
print "$array[2]\n";
^Z
5, 6, first, 1, second, 2, third, 3, 34, Jack Sprat

first

    ******************
If you wish to make progress in the direction of multi-dimensional data structures, 
you *must* become adept at using
references.  Perl provides no alternate means of handling the issue.

> Here is what I tried, unsuccessfully
>
> no strict 'refs'
>
> # @TERMS is an array of each sub-directory name up to the one containing the target 
> file
>
>     my(%NAV_HASH);
>            # Build the multi-dimensional hash
>              my($hash_string) = "NAV_HASH";
>              foreach my $sub_dir (@TERMS){
>                  $hash_string .= "{\"$sub_dir\"}";
>              }
>              print "hash_string = $hash_string\n" if ($DEBUG == 1);  # <- This looks 
> good
>              # Producing a hash_string = 
> NAV_HASH{"Africa"}{"focus_regions"}{"OEF_Somalia"}{"Overview"}{"high_low_cloud"}
>
>              # Now turn this string into a real hash and
>              # assign it a value
>              $$hash_string = "$last,";

Strings are data.  Hashes and variables are programming structures.  Don't try to mix 
the two.

my $volume_root = {};

$volume_root->{'Program Files'} = {};
$volume_root->('WinBlows'} = {};
$volume_root->{'WinBlows'}->{'System32'} = {};

Actually, here you could skip the second statement, even, since the assignment to a 
sub-reference auto-vivifies the keys in
between.

Greetings! E:\d_drive\ocf\discuss\prototype>perl -w
my $volume_root = {};
$volume_root->{'WinBlows'}->{'System32'} = {};
$volume_root->{'WinBlows'}->{'System32'}->{'name'} = 'Dirty Tricks';
print "$volume_root->{'WinBlows'}->{'System32'}->{'name'}\n";
^Z
Dirty Tricks

Note that this is all hard-coded, though.  The program structures were never strings 
per-se, in the same sense as data
strings.

A practical [and working] example from my current project:

#  In function launch_full_text_search:

  my $file_keys = [sort {$a <=> $b} keys %$files];   #  %$files => hash pointed to by 
$files
  while (my $file_key = shift @$file_keys) {           #  @$file_keys => array pointed 
to by $file_keys
    seek_full_text_in_file($regex, $file_key, $files, $found_in)
  }

In the called function, seek_full_text_in_file:


sub seek_full_text_in_file {
  my ($regex, $file_key, $files, $found_in) = @_;

  my $file = $files->{$file_key};
  open IN, $file or die "Could not open $file $!";
  my $line;
  $line = <IN> until $line and $line eq "\x0A";
  {
    local $/;
    $line = <IN>;
    $line =~ s/[\012\015]/ /g;
    if (my $count = () = $line =~ /$regex/gi) {
      $found_in->{$file_key}->{filename} = $file if not $found_in->{$file_key};
      $found_in->{$file_key}->{count} += $count;
    }
  }
}

This does not get as deeply nested as a directory tree, of course, but you should be 
able to see how references link together
the layers of the structure.  Once you get the hang of using references, you can use 
them to drill down as far into
structures as you want.  Note also that the original structures in the calling 
function are modified by the actions using the
reference.  This can be very powerful.

perldoc perlref
perldoc perlreftut

Joseph



-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to