in reply to Complex Data Structures

Ok, well. Lets see.

use warnings;
use strict;

NEVER write anything with using strict and warnings, (at least until you dont have to ask questions like this :-)
Ok so now we have that out of the way, lets look at the code. Unless your description of what you want to do and what you are doing it with is completely wrong then you have some problems with your code, problems which frankly make it hard to give you a solution.
Heres your code broken down into lines.
for $type (keys %$curr_struct_pos) {

You should use the my keyword. Combined with use strict it keeps you from misspelling variables and wondering why the code has broken (amongst many other things.)
for ($a=1;$$curr_struct_pos{$type}[$a];$a++) {

This has two problems, the first being that it is not _really_ perl, but cish-perl. (A sea pearl! 8-) Its not wrong, but of a style that makes a perl programmer wonder what special things you are doing to need to use this form of 'for'. But as you arent doing anything special so it probably better to to use the more commonly used list form.
for my $var ($begin..$end) {#blah}
Overlooking that, there is a subtle error that could _really_ cause you problems if you use the sort function.(especially as you arent using my or strict or warnings)
The error I am refering to is the use of the dynamic (AKA global) variable $a.
Perl uses the global variables $a and $b to pass elements of a sort into a custom block, as below:
my @sorted=sort {$a <=> $b} @numlist;
Notice the 'my'? :-)
A question regarding this is should $a really be inited to 1? Arrays in perl start at 0 normally.
Ok the next thing is just exactly what do you mean by:
$$curr_struct_pos{$type}[$a]
I have a feeling that you think this means something that it does not. Do you think it refers to the element $a of the array stored against the key $type in some hash? Well it doesnt. The $$cur_struct_pos{... actually is a symref to whatever the scalar $cur_struct_pos happens to point at. To prove it run the following code:
use strict; use warnings; my %curr_struct_pos; my $curr_struct_pos="hello"; my $type="key"; my $index=0; $$curr_struct_pos{$type}[$index]++;
Which will produce the error:
Can't use string ("hello") as a HASH ref while "strict refs" in use at D:\Development\Perl\google\monk1.pl line 8.
So you will have to rewrite that... Maybe like $curr_struct_pos{$type}->$index;
$path = "Global${type}Def:$$curr_struct_pos{$type}[$a].def";
Ok so the same issue as before with $$curr_struct_pos. use strict; use warnings; !!!!!! And basically the rest of the code is ununderstandable because of this error.
I will provide you with what I THINK you are trying to do and maybe you can correct me.
for my $type (keys %$curr_struct_pos) { for my $index (1..@{$cur_struct_pos{$type}}-1) { $path="Global".$type. "Def:".$curr_struct_pos{$type}[$a]. ".def"; #much easier to read $curr_struct_pos{$type}[$a] = extract(); }
Now I understand you want to take the strings in the array and turn them into keys in a hash right? Well in general terms this is how you would do it (its a FAQ BTW);
my %hash; my @list=qw(These elements are going to become keys); map {$hash{$_}++} @list; #or $hash{$_}++ foreach @list; #or with refs... my $hash_ref =\%hash; my $array_ref=\@list; $hash->{$_}++ foreach @$list;

So to sum up I would say that you should go over perlreftut very carefully once again (you _have_ read it right?), and
use strict; use warnings; until you can send me a mail telling me why you dont think you should have to, and being correct in what you say.
Im sorry I dont mean to be a bitch, but the golden rule that all the newbies break is this one. Virtually all of their problems disappear when they start using it.
HTH
Yves
--
You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

Replies are listed 'Best First'.
Re: Re: Complex Data Structures
by demerphq (Chancellor) on Aug 30, 2001 at 23:52 UTC
    I apologise. I noticed a minor problem in my interpretation of your code. So assuming that the hash we are dealing with is defined something like:
    my %curr_struct_pos;
    Then this should do:
    for my $type (keys %curr_struct_pos) { for my $index (0..@{$cur_struct_pos{$type}}-1) { $path="Global".$type. "Def:".$curr_struct_pos{$type}->[$a]. ".def"; $curr_struct_pos{$type}->[$a] = extract(); }
    On the other hand if it is a reference to a hash that you have there then this should do:
    for my $type (keys %$curr_struct_pos) { for my $index (0..@{$cur_struct_pos->{$type}}-1) { $path="Global".$type. "Def:".$curr_struct_pos->{$type}[$a]. ".def"; $curr_struct_pos->{$type}[$a] = extract(); }
    As for extract() I believe you can work that one out for yourself from my other post.

    Yves
    --
    You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)
      Thanks for the replies. I will have a look at it but I think I am going to use a different data structure instead. I promise I will use strict and warnings in future. Just for the record the variables were
      $curr_struct_pos = "string"; %$curr_struct_pos;
      and I wanted the new hash to have the same name as the string in the array - not the keys of the hash. Also
      $path = "Global${type}Def:$$curr_struct_pos{$type}[$a].def";
      does give me the correct paths. I have only been using Perl for less than two weeks so forgive my Cish Perl.
        Just for the record the variables were
        $curr_struct_pos = "string"; %$curr_struct_pos;
        Ok. So it was deliberate. My apologies for getting a little agro about it then... OTOH, why are you doing this? Why do you want to get a reference to a hash this way? Why not use a hard ref?
        Most perlmongers would avoid doing this type of thing except in very unusual circumstances, for many reasons. (You will see many threads this subject in CLPM if you do a search for 'symrefs')
        Normally the same result can be achieved in a much more readable and safer way by using a hash. Foinstance our toplevel of the data structure could be
        #assume strict and warnings! my %hash=(string=>{});
        and you would access it like
        $hash{string}->{$key}->[$index]=$whatever;

        and I wanted the new hash to have the same name as the string in the array - not the keys of the hash
        One of us is a bit confused here. What do you mean by the hash having the same name? My understanding is that you will be using anonymous hshes, which have no name. Unless you are evaling named hashes (or symrefs i suppose) into scope you cant do what I think you are saying.
        $path = "Global${type}Def:$$curr_struct_pos{$type}[$a].def"; does give me the correct paths.
        I can believe (now that you have explained that are using symrefs deliberately) that it _works_. But its in a style that IMHO will give you trouble.
        I gave you one interpretation in the earlier post, but now that I understand that you have some idea of what you are doing (even if it is not to be advised) I could give you another way to write it:
        $path = "Global".$type. "Def:".$curr_struct_pos->{$type}[$a]. ".def";
        For me this is easier to understand at a glance, and therefore more maintainable, also it gets rid of that confusing ugly and confusing $$ and replaces it with $var_name-> which should produce the same result.
        Anyways, I suppose Ill stop lecturing, but I will repeat that probably have no good reason to use symrefs, that you can accomplish what you want without them, and have much easier to understand and maintain code.

        If you are going to play around with symrefs a lot then you should have a look at this (after you have read perlreftut):
        sub dump_symbol_table { print "SYMBOL TABLE\n--------------------------------------------- +----------\n"; foreach my $key (sort keys %::) { next unless $key=~/^[\x20-\xff]/; (my $value=$::{$key})=~s/([\x00-\x1f])/sprintf("\\x%02x",ord($ +1))/ge; printf "%20s = %-20s\n",$key,"'$value'"; } print "\n"; } my $symref="hash"; ${$symref}{key}="value"; print "Keys in 'our %hash':".join(",",keys %$symref)."\n"; BEGIN { dump_symbol_table } END { dump_symbol_table }
        Oh and I had the tagline before writing this...

        Yves
        --
        You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)