Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

adding to a hash

by powerhouse (Friar)
on May 13, 2003 at 19:06 UTC ( [id://257869]=perlquestion: print w/replies, xml ) Need Help??

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

I have a hash that contains variables and I want to add to it, so can I do this:
%variables .= get_page_content("names");
So that it will not delete the variables it already has, but will just add the rest to it?


Replies are listed 'Best First'.
Re: adding to a hash
by MrYoya (Monk) on May 13, 2003 at 19:10 UTC
    The .= operator only applies to strings.
    To add to a hash, try this:
    $variables{variable_name} = get_page_content("names");

    Please please get yourself a copy of Learning Perl, it'll pay off :)

Re: adding to a hash
by Limbic~Region (Chancellor) on May 13, 2003 at 19:31 UTC
    When you the % sigil for a hash (%hash =), you are saying:

    Assign the entire hash to

    To assign an individual key/value pair try:

    $hash{'key1'} = 4; $hash{'key2'} = 5;
    You will notice that the % sigil has change to a $. Remember that $ looks like the s in scalar. It means just a single piece of data. When you get a little more advanced, you can check out hash slices.

    There are plenty of resources for learning Perl:

  • which even has free on-line books
  • Perl FAQ for frequently asked questions
  • Perlmonks Q&A
  • Learning Perl - (dead tree) O'Reilly

    Cheers and keep trying


Re: adding to a hash
by pzbagel (Chaplain) on May 13, 2003 at 19:29 UTC

    Generally speaking, if you are getting variable name/value pairs then adding them to the hash is simply a matter of:


    Because you mention that you don't want to delete variables that are already there, I wonder if you mean that some of the variables you are reading in may already be in the hash. If that is the case, you can make sure they are not in the hash by doing something like this when you assign the values:


    That little ||= keeps a value in the hash if it is there or assigns a new key/value pair if it is not defined yet.

    The question here is: What exactly is get_page_content() returning? A scalar? array? reference? If you can tell us this, we can give you a more specific anwer.


      That little ||= keeps a value in the hash if it is there or assigns a new key/value pair if it is not defined yet.

      Oops. You have to be a little more careful than that. Your code will perform the assignment even in the case that a previous false value exists. For example:

      $h{key} = 0; $h{key} ||= "foo"; print $h{key};

      If you really want to check for definedness, you should use defined(). Often, though, there are situations where undef is a valid value too and in those cases you should use exists() to check whether the hash key exists yet. Here is one way to do that succinctly:

      $h{$key} = "value" unless exists $h{$key};

      "My two cents aren't worth a dime.";
Re: adding to a hash
by Thelonius (Priest) on May 13, 2003 at 19:51 UTC
    Not unless get_page_content("names") returns a key-value paired list.
    Well, duh, but that's implied by his question.
    Plus, that's just a silly way of doing it.
    I don't think it's silly, just inefficient. How about this:
    sub pushhash (\%@) { my $hash = shift; my $key; $$hash{$key} = shift while defined($key = shift); } my %a; $a{cow} = "COW1"; $a{dog} = "DOG1"; pushhash %a, cow => "COW2", bull => "Terrier"; for (sort keys %a) { print "$_ => $a{$_}\n"; }
Re: adding to a hash
by Thelonius (Priest) on May 13, 2003 at 19:38 UTC
    You can do this:
    %variables = (%variables, get_page_content("names"));
    although it's not the most efficient thing in the world.
      Not unless get_page_content("names") returns a key-value paired list. Plus, that's just a silly way of doing it.

      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: adding to a hash
by powerhouse (Friar) on May 13, 2003 at 20:18 UTC
    Wow, thanks for all the replies :o)

    I am using the sub get_page_content to get variables in a database.

    I took the advice of another monk and added a type to the table, so I am passing the "type" only, and it is getting all those variables and putting them in the hash. So It looks like this:

    sub get_page_content { my $type = shift; my $dbh = DB_File::connect(); $sth = $dbh->prepare (qq{ SELECT `name`,`value` FROM `page_variabl +es` WHERE `type` = ? }); $sth->execute($type); my %temp_vars; # WILL THIS KILL THE REST OF THE VALUES? while(my ($db_name,$db_content) = $sth->fetchrow_array()) { $temp_vars{$db_name} = $db_content; } $sth->finish(); return(%temp_vars); }
    Since I call this with %variables = get_page_content("name"); that would replace the whole hash, right? OR would it just append the new variables to this list? They will always be unique, as the column `name` has to be unique, or it will error out, when adding new records to the db.


    BTW, I do have quite a few Perl books, but I have only read two of them("Perl Cookbook" and "Perl and Mysql for the Web"). I'm by no means a Perl guru. ;o)
    When I have more time on my hands I'll devour the Others! :o)
      Remember that = is an assignment operator, not an addition or concatenation operator. When you use it, you are telling Perl to set the left-hand side equal to the right-hand side. All entries in the hash will be replaced.

      You have two options: You can either iterate through the replacement key/value pairs and set the $hash{$key} = $value, or if your list of keys and values are known ahead of time, a hash slice might let you make a change to a group of hash entries with one statement (e.g. @hash{@new_keys} = @new_values).

Re: adding to a hash
by powerhouse (Friar) on May 13, 2003 at 20:28 UTC
    How effecient would this be:
    When I call the get_page_content("names"); what if I passed the current hash there, and just had the sub get_page_content intercept it, and instead of doing
    my $temp_vars;
    I could do:
    my ($type,%temp_vars) = @_;
    Then it would be pre-populated with all the current data, and add all the new data, then pass it back in the return.

    Would that be a "secure" or good way of doing it?

      That would work, but it would be more efficient to pass the hash by reference:
      get_page_content(\%variables, "names"); # instead of %variables = get_page_content("names"); sub get_page_content { my ($hashref, $type) = @_; my $dbh = DB_File::connect(); $sth = $dbh->prepare (qq{ SELECT `name`,`value` FROM `page_variabl +es` WHERE `type` = ? }); $sth->execute($type); while(my ($db_name,$db_content) = $sth->fetchrow_array()) { $$hashref{$db_name} = $db_content; } $sth->finish(); }
Re: adding to a hash
by BrowserUk (Patriarch) on May 14, 2003 at 12:40 UTC

    Tom Christiansen, the author of the well-worth reading FMTEYEWtKaPiP shows this neat function.

    sub hpush(\%@) { my $href = shift; # NB: not % while ( my ($k, $v) = splice(@_, 0, 2) ) { $href->{$k} = $v; } }

    Which you could use to this

    hpush(%variables, get_page_content("names"));

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
Re: adding to a hash
by Skeeve (Parson) on May 14, 2003 at 06:58 UTC
    Flame me if it's already told before :-) I couldn't find it.

    How about returning a reference to your %temp_vars and adding your new variables like this:
    # This would be the return statement of get_page_content return \%temp_vars; # And this would be the call: $new_variables = get_page_content("names"); # $new variables is a reference to your result @variables{keys %$new_variables}=values %$new_variables;
    Of course this will overwrite all variables that exist in both %tempvars and %variables with the value found in %temp_vars.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://257869]
Approved by dragonchild
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-20 01:47 GMT
Find Nodes?
    Voting Booth?

    No recent polls found