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

I'm not even sure if the title is accurate, I'm super stumped. I want to grab a whole bunch of stuff from CGI's param and shove it in a hash, something like what was discussed on this node. The problem is that strict keeps complaining that my %hash needs an explicit name, which I thought i gave it?
#!/usr/bin/perl -w use CGI qw(:standard); use strict; $! = 1; print header; my $try = CGI->new(); my %hash; # tried 'my $hash = {};' too... foreach my $string ( $try->param ) { if ( $string =~ m/(\d+)_(\d+)/ ) { push @{$hash->{$1}->{$2}}, $try->param($string); } } print qq! <HTML><HEAD><TITLE></TITLE></HEAD> <P> then you have:<BR><P>$hash{12}{1} <BODY></BODY></HTML>!;

Replies are listed 'Best First'.
Re: hash name not sticking?
by chromatic (Archbishop) on Sep 05, 2000 at 02:36 UTC
    You need to take a look at perlref, if you want to use a hash reference (my $hash = {};). Since you say you don't want to do that, you need to get rid of the dereferencing arrows in your push line.

    Try this instead:

        push @{$hash{$1}{$2}}, $try->param($string);

    The arrows are only necessary to tell Perl that you want at data stored in the hash pointed to by the scalar $hash. Since you want at a scalar stored in %hash, you don't need the arrow. (Yes, using a HoHoL makes you use more punctuation, but I think you get the drift.)

    Remember, the punctuation on the front of the variable name tells you want kind of value you want to use in that case -- it's not part of the variable's name. The arrow helps distinguish between a scalar portion of a hash and a scalar hash (de)reference. (Does this make it clear? I'm not sure I would understand it if I had to read what I'd just written. :| )

      for the curious, i'm an idiot :)

      in the past i have always created anon hashes setting arrays = arrays. well, this time it should have been scaler = scaler, but i just didn't see it. everything else fell out of doing that all wrong. code i ended up using:

      my %hash; foreach my $string ( $try->param ) { if ( $string =~ m/(\d+)_(\d+)/ ) { $hash{$1}{$2} = $try->param($string); } }
      and  <P> then you have:<BR><P>$hash{12}{1} which prints "then you have STRING".
Re: hash name not sticking?
by ar0n (Priest) on Sep 05, 2000 at 00:45 UTC
    push @{$hash->{$1}->{$2}}, $try->param($string);
    This line tells me you're using $hash as a reference to an anonymous hash.
    Changing my %hash to my $hash should do the trick (unless i'm missing something).

    update
    d'oh. The real problem is in your html. Change this:
    <P> then you have:<BR><P>$hash{12}{1}
    to this:
    <P> then you have:<BR><P>$hash->{12}->{1}
    You just forgot to dereference. If you want to print anything meaningful (i.e. not ARRAY(0x812cd54)), you'll have to dereference it some more.

    -- ar0n (just another perl joe)

      that seems to have no effect. I had already tried it (see the comment in the code) but i tried it again, both with and without '= {}' to see what would happen.

      the only interesting effect is that when I use 'my %hash' i get 'Global symbol "$hash" requires explicit package name...' and when i use 'my $hash' i get 'Global symbol "%hash" requires explicit package name...'. just weird.

RE (tilly) 1: hash name not sticking?
by tilly (Archbishop) on Sep 05, 2000 at 00:47 UTC
    Do you want a variable $hash or a hash %hash? You need to make your declaration match what you are using it as. In your push you are using $hash as a reference to a hash, in your print you are looking up a value in %hash. This will not work well since they are different things, and that is why neither of your attempts at declaring it managed to do away with the problem.
      i want hash %hash. so that i can call the values as in the HTML.
      my $hash = {}; ... push @{$hash{$1}{$2}}, $try->param($string); ... <P> then you have:<BR><P>$hash{12}{1}
      same error
Re: hash name not sticking?
by agoth (Chaplain) on Sep 05, 2000 at 12:08 UTC

    Why not use the supplied (from the CGI docs) :
    I dont know if theres any significant overhead?

    my $q = new CGI; $params = $q->Vars; print $params->{'address'}; @foo = split("\0",$params->{'foo'}); %params = $q->Vars;