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

Please help. Is it possible to do something like these:
%hash = (); # How to create a hash with keys only? As at this point I +don’t have its value. @insert = \%hash; $insert[0] = $ages->{‘Sharon’}; $insert[1]=$ages->{'Martin’}; %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); : : $sqlquery -> execute(@insert);
First, I have an empty hash. Then, an array saved the specific hash value. After that, the hash will contain its values. The array will contain the hash value “automatically”. Is it possible? Please advice and help. Thanks.

Replies are listed 'Best First'.
Re: array/hash - reference and dereference
by kyle (Abbot) on Jan 09, 2009 at 03:51 UTC

    Now I'm guessing what you want to do is kind of like this:

    my @peeps = qw( Martin Sharon Rikke ); my %ages; $ages{'Martin'} = 44; $ages{'Rikke'} = 12; $ages{'Sharon'} = 23; my @insert = @ages{@peeps}; # @insert = ( 44, 23, 12 )

    What you're asking to do is take references to the elements of %ages and store them in @insert so that you can modify @insert via %ages. Maybe what you really want is aliases, but you seem to be asking for this...

    my @peeps = qw( Martin Sharon Rikke ); my %ages; @ages{@peeps} = (); # make keys with undef values # take references to the values my @insert = \@ages{@peeps}; # same thing but more explicit $insert[0] = \$ages{'Martin'}; $insert[1] = \$ages{'Sharon'}; $insert[2] = \$ages{'Rikke'}; # same thing but shorter push @insert, \$ages{$_} for @peeps; $ages{'Martin'} = 44; $ages{'Rikke'} = 12; $ages{'Sharon'} = 23; my @ages_array = map { ${$_} } @ages{@peeps};

    In that case, each element of @insert is a scalar reference to some value in %ages. To get (or modify) those values via @insert, you have to dereference them (e.g., ${$insert[1]}), so that's not exactly what you're asking for either.

    For more on references, see perlreftut, perlref, and References quick reference.

      Thanks.
      take references to the elements of %ages and store them in @insert so that you can modify @insert via %ages.
      Yes, that is what I am looking for. Thank you very much. And yes, I will have problem on:
      $sqlquery->execute(@insert);
      As I have to dereference them.

      The purpose of this idea is to speed up the SQL process. But now, it seems this idea can't work.

      Again, a big thank you to all of you.
Re: array/hash - reference and dereference
by fullermd (Vicar) on Jan 09, 2009 at 03:04 UTC

    I'm confused on just what you're trying to do. I'm not sure you aren't as well.

    # How to create a hash with keys only?

    That's nonsensical. Keys are a way to find a value. You can create a hash of keys whose value is undef or 0 or an empty string or any temporary placeholder you want, but you can't have a "hash with keys only".

    @insert = \%hash;

    This creates a 1-array whose first element is a reference to an empty hash. I don't think that's what you want to do.

    The rest of the code is at least superficially reasonable (if you put %ages before the lines where you try and reference it), but what's the purpose of %hash? What are you wanting to end up with?

      O..my mistake..%hash %ages Sorry.
      %ages = ('Martin' => 0, 'Sharon' => 0, 'Rikke' => 0); #this way? @insert = \%hash; #at this point, what is the correct way to save the hash into an array +? $insert[0] = $ages->{‘Sharon’}; $insert[1]=$ages->{'Martin’}; %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); : : $sqlquery -> execute(@insert);
      My idea is: When the script start, I don't have the hash values. So,I want to create "pointer" points to the hash. And "save" the specific hash value into an array. Later, when the hash values are fetched, I can just run:
      $sqlquery -> execute(@insert);
      Please advise. Thanks.

        It sounds like a lot more trouble than just making a mkinsert() function.

        %ages = [...] # Finally filled in $sqlquery->execute(mkinsert(%ages));

        You could store references to the hash elements into the array instead. But you'd have to explicitly dereference them, and it would mostly serve to confuse people reading the code. Why not make it simple?

        O..Sorry...my mistake..%hash %ages
        %ages = ('Martin' => 0, 'Sharon' => 0, 'Rikke' => 0); #this way? @insert = \%ages; #at this point, what is the correct way to save the hash into an array +? $insert[0] = $ages->{‘Sharon’}; $insert[1]=$ages->{'Martin’}; %ages = ('Martin' => 28, 'Sharon' => 35, 'Rikke' => 29); : : $sqlquery -> execute(@insert);
        My idea is: When the script start, I don't have the hash values. So,I want to create "pointer" points to the hash. And "save" the specific hash value into an array. Later, when the hash values are fetched, I can just run:
        $sqlquery -> execute(@insert);
        Please advise. Thanks.
Re: array/hash - reference and dereference
by kyle (Abbot) on Jan 09, 2009 at 03:36 UTC

    If you're trying to do a SQL insert based on a hash, SQL::Abstract may work for you.

    use SQL::Abstract; my $abstractor = SQL::Abstract->new(); my %value_of = ( name => 'Martin', age => 28 ); my ($stmt,@bind) = $abstractor->insert( 'table', \%value_of ); $dbh->do( $stmt, undef, @bind );

    If you want to make a hash with keys and not values, that doesn't make sense, as fullermd says. You can, however, easily get a hash with all values set to undef like so:

    my %h; @h{@keys_wanted} = ();