Merging potentially undefined hashes

Discussion in 'Perl Misc' started by Derek Basch, Jun 9, 2006.

  1. Derek Basch

    Derek Basch Guest

    Hi everyone,

    I have several functions (getBillingDatabaseAttributes, etc...) that
    can either return a hash reference or undefined. They just return a DBI
    selectrow_hashref function such as:

    $hash_ref = $dbh->selectrow_hashref($statement);

    How can I merge these hashes and undefined values?

    If I do this:

    %hash1 = (%$hash2, %$hash3);

    I get a 'cant reference undefined value' error.

    Here is my attempt at an idiom to handle this. Haven't tested it:

    push(@user_attributes, $self->getBillingDatabaseAttributes($user_id));
    push(@user_attributes, $self->getBoardsDatabaseAttributes($user_id));
    push(@user_attributes, $self->getMembersDatabaseAttributes($user_id));

    foreach (@user_attributes) {
    %user_attributes = (@_, %user_attributes);
    }

    Am I on the right track?
     
    Derek Basch, Jun 9, 2006
    #1
    1. Advertising

  2. Derek Basch

    Ben Morrow Guest

    Quoth "Derek Basch" <>:
    > Hi everyone,
    >
    > I have several functions (getBillingDatabaseAttributes, etc...) that
    > can either return a hash reference or undefined. They just return a DBI
    > selectrow_hashref function such as:
    >
    > $hash_ref = $dbh->selectrow_hashref($statement);
    >
    > How can I merge these hashes and undefined values?
    >
    > If I do this:
    >
    > %hash1 = (%$hash2, %$hash3);
    >
    > I get a 'cant reference undefined value' error.


    Do you mean a 'Can't use and undefined value as a HASH reference' error?
    Please be precise.

    > Here is my attempt at an idiom to handle this. Haven't tested it:
    >
    > push(@user_attributes, $self->getBillingDatabaseAttributes($user_id));
    > push(@user_attributes, $self->getBoardsDatabaseAttributes($user_id));
    > push(@user_attributes, $self->getMembersDatabaseAttributes($user_id));
    >
    > foreach (@user_attributes) {
    > %user_attributes = (@_, %user_attributes);
    > }
    >
    > Am I on the right track?


    Well, I would just use

    my %hash1 = map %$_, grep defined, $hash2, $hash3;

    Ben

    --
    Joy and Woe are woven fine,
    A Clothing for the Soul divine William Blake
    Under every grief and pine 'Auguries of Innocence'
    Runs a joy with silken twine.
     
    Ben Morrow, Jun 9, 2006
    #2
    1. Advertising

  3. Derek Basch

    Paul Lalli Guest

    Derek Basch wrote:
    > I have several functions (getBillingDatabaseAttributes, etc...) that
    > can either return a hash reference or undefined. They just return a DBI
    > selectrow_hashref function


    Careful with your terminology. They are not returning functions. They
    are returning the return value of another function. Rather large
    distinction.

    > such as:
    >
    > $hash_ref = $dbh->selectrow_hashref($statement);
    >
    > How can I merge these hashes and undefined values?
    >
    > If I do this:
    >
    > %hash1 = (%$hash2, %$hash3);
    >
    > I get a 'cant reference undefined value' error.


    How about:
    %hash1 = map { defined $_ ? %{$_} : () } ($hash2, $hash3);

    And here's a short-but-complete script that demonstrates its use:
    perl -MData::Dumper -e'
    $h2 = undef;
    $h3 = { foo => q{bar}, baz => q{biff} };
    $h4 = undef;
    $h5 = { alpha => q{beta} };
    %h1 = map { defined $_ ? %{$_} : () } ($h2, $h3, $h4, $h5);
    print Dumper(\%h1);
    '
    $VAR1 = {
    'foo' => 'bar',
    'baz' => 'biff',
    'alpha' => 'beta'
    };

    > Here is my attempt at an idiom to handle this. Haven't tested it:


    Why would you post code that you've written but haven't tested? What
    was the stumbling block to actually testing it? For all you know, your
    code may work perfectly, and you're wasting the time of hundreds of
    other people who are reading your question.

    > push(@user_attributes, $self->getBillingDatabaseAttributes($user_id));
    > push(@user_attributes, $self->getBoardsDatabaseAttributes($user_id));
    > push(@user_attributes, $self->getMembersDatabaseAttributes($user_id));
    >
    > foreach (@user_attributes) {
    > %user_attributes = (@_, %user_attributes);
    > }
    >
    > Am I on the right track?


    No. And if you'd run the above code and let Perl tell you what's wrong
    with it, you'd know why. There are at least 3 things wrong with the
    above code. I leave you to figure out what they are.

    Paul Lalli
     
    Paul Lalli, Jun 9, 2006
    #3
  4. Derek Basch wrote:
    > Hi everyone,
    >
    > I have several functions (getBillingDatabaseAttributes, etc...) that
    > can either return a hash reference or undefined. They just return a DBI
    > selectrow_hashref function such as:
    >
    > $hash_ref = $dbh->selectrow_hashref($statement);
    >
    > How can I merge these hashes and undefined values?
    >
    > If I do this:
    >
    > %hash1 = (%$hash2, %$hash3);
    >
    > I get a 'cant reference undefined value' error.


    My preferred idiom is:

    %hash1 = (%{ $hash2 || {} }, %{ $hash3 || {} });

    Or:

    %hash1 = (%{\%$hash2}, %{\%$hash3});
     
    Brian McCauley, Jun 9, 2006
    #4
  5. Derek Basch

    Ben Morrow Guest

    Quoth Ben Morrow <>:
    >
    > Do you mean a 'Can't use and undefined value as a HASH reference' error?
    > Please be precise.


    Hoist. Petard.

    I meant s/and/an/, of course :)

    Ben

    --
    'Deserve [death]? I daresay he did. Many live that deserve death. And some die
    that deserve life. Can you give it to them? Then do not be too eager to deal
    out death in judgement. For even the very wise cannot see all ends.'
     
    Ben Morrow, Jun 9, 2006
    #5
  6. Derek Basch

    Derek Basch Guest

    Ummmm... I was asking people for their ideas on what the proper idiom
    to handle this problem was. The code I wrote was simply to convey a
    concept because I knew that I was going about it the wrong way. Why
    test code that you know is wrong? Especially, when it is only
    pseudocode and you clearly state that it is such.

    I don't understand why some people on this list are so angry? I wrote
    questions just like this on the python list for years and never once
    got yelled at. I searched long and hard for previous answers to this
    problem and found none. Only then did I post the question.

    Anyways, thanks to everyone for the answers. I never would have thought
    of these solutions on my own.

    Paul Lalli wrote:
    > > Here is my attempt at an idiom to handle this. Haven't tested it:

    >
    > Why would you post code that you've written but haven't tested? What
    > was the stumbling block to actually testing it? For all you know, your
    > code may work perfectly, and you're wasting the time of hundreds of
    > other people who are reading your question.
     
    Derek Basch, Jun 9, 2006
    #6
  7. Derek Basch

    David Squire Guest

    Derek Basch wrote:
    > Ummmm... I was asking people for their ideas on what the proper idiom
    > to handle this problem was. The code I wrote was simply to convey a
    > concept because I knew that I was going about it the wrong way. Why
    > test code that you know is wrong? Especially, when it is only
    > pseudocode and you clearly state that it is such.
    >
    > I don't understand why some people on this list are so angry? I wrote
    > questions just like this on the python list for years and never once
    > got yelled at. I searched long and hard for previous answers to this
    > problem and found none. Only then did I post the question.


    ....and now you're top-posting. Grrrr.

    >
    > Paul Lalli wrote:
    >>> Here is my attempt at an idiom to handle this. Haven't tested it:

    >> Why would you post code that you've written but haven't tested? What
    >> was the stumbling block to actually testing it? For all you know, your
    >> code may work perfectly, and you're wasting the time of hundreds of
    >> other people who are reading your question.

    >
     
    David Squire, Jun 9, 2006
    #7
  8. Derek Basch

    Derek Basch Guest

    Stupid google groups. I sometimes forget to fix the top posting because
    it puts the cursor at the top and auto quote everything below. My
    apologies.

    David Squire wrote:
    > Derek Basch wrote:
    > > Ummmm... I was asking people for their ideas on what the proper idiom
    > > to handle this problem was. The code I wrote was simply to convey a
    > > concept because I knew that I was going about it the wrong way. Why
    > > test code that you know is wrong? Especially, when it is only
    > > pseudocode and you clearly state that it is such.
    > >
    > > I don't understand why some people on this list are so angry? I wrote
    > > questions just like this on the python list for years and never once
    > > got yelled at. I searched long and hard for previous answers to this
    > > problem and found none. Only then did I post the question.

    >
    > ...and now you're top-posting. Grrrr.
    >
    > >
    > > Paul Lalli wrote:
    > >>> Here is my attempt at an idiom to handle this. Haven't tested it:
    > >> Why would you post code that you've written but haven't tested? What
    > >> was the stumbling block to actually testing it? For all you know, your
    > >> code may work perfectly, and you're wasting the time of hundreds of
    > >> other people who are reading your question.

    > >
     
    Derek Basch, Jun 9, 2006
    #8
  9. Derek Basch

    Derek Basch Guest

    Stupid google groups. I sometimes forget to fix the top posting because
    it puts the cursor at the top and auto quote everything below. My
    apologies.
     
    Derek Basch, Jun 9, 2006
    #9
  10. Derek Basch

    Derek Basch Guest

    Derek Basch wrote:
    > Stupid google groups. I sometimes forget to fix the top posting because
    > it puts the cursor at the top and auto quote everything below. My
    > apologies.


    Hahahhahahaahhahahha. Now i double posted and top posted. Great day for
    Derek. Jeez.
     
    Derek Basch, Jun 9, 2006
    #10
  11. Derek Basch <> wrote:

    > I have several functions (getBillingDatabaseAttributes, etc...) that
    > can either return a hash reference or undefined. They just return a DBI
    > selectrow_hashref function such as:
    >
    > $hash_ref = $dbh->selectrow_hashref($statement);



    Use the standard idiom for applying a default value:

    $hash_ref = $dbh->selectrow_hashref($statement) || {};


    > How can I merge these hashes and undefined values?
    >
    > If I do this:
    >
    > %hash1 = (%$hash2, %$hash3);
    >
    > I get a 'cant reference undefined value' error.



    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Jun 9, 2006
    #11
  12. Derek Basch

    Paul Lalli Guest

    Derek Basch wrote:
    > Ummmm... I was asking people for their ideas on what the proper idiom
    > to handle this problem was. The code I wrote was simply to convey a
    > concept because I knew that I was going about it the wrong way. Why
    > test code that you know is wrong? Especially, when it is only
    > pseudocode and you clearly state that it is such.


    Uh. You have a different definition of either "clearly" or
    "pseudo-code" than I do. Allow me to re-quote you:

    > > > Here is my attempt at an idiom to handle this. Haven't tested it:


    That, to you, is the equivalent of "this is pseudo-code"? Sounds to me
    like it was an attempt to write real code, but you couldn't be bothered
    to type "perl -c" and wanted us to do it for you.

    > I don't understand why some people on this list are so angry?


    Because your post amounted to "I'm lazy and don't feel like checking
    this, so please do it for me."

    > I wrote
    > questions just like this on the python list for years and never once
    > got yelled at.


    Explain to me where you "got yelled at". Hell, there weren't even any
    exclamation marks in my post. Or are you suggesting that anyone who
    tells you you're doing something wrong is "yelling" at you?

    > I searched long and hard for previous answers to this
    > problem and found none. Only then did I post the question.


    Uh-huh, and? I don't recall my post deriding you for not searching
    long enough. I asked you why you would write what you believed to be a
    way to solve the problem, but didn't even bother testing it. Even if
    you knew it was "wrong", you don't think the compiler and run-time
    results of such code might lead you to the right answer? Sounds like
    you have remarkably little faith in your coding and debugging skills.

    > Anyways, thanks to everyone for the answers.


    You're welcome.

    Paul Lalli
     
    Paul Lalli, Jun 10, 2006
    #12
  13. Derek Basch

    Lee Guest

    Derek Basch wrote:
    > $hash_ref = $dbh->selectrow_hashref($statement);


    A very quick scan of the thread didn't show a reference to Hash::Merge,
    whose source you may find helpful, even if the whole is too cumersome
    for you:

    http://search.cpan.org/~mneylon/Hash-Merge-0.07/

    lee
     
    Lee, Jun 12, 2006
    #13
  14. Derek Basch

    farans Guest

    On Fri, 09 Jun 2006 11:46:17 -0700, Brian McCauley wrote:

    >
    > Derek Basch wrote:
    >> Hi everyone,
    >>
    >> I have several functions (getBillingDatabaseAttributes, etc...) that
    >> can either return a hash reference or undefined. They just return a DBI
    >> selectrow_hashref function such as:
    >>
    >> $hash_ref = $dbh->selectrow_hashref($statement);
    >>
    >> How can I merge these hashes and undefined values?
    >>
    >> If I do this:
    >>
    >> %hash1 = (%$hash2, %$hash3);
    >>
    >> I get a 'cant reference undefined value' error.

    >
    > My preferred idiom is:
    >
    > %hash1 = (%{ $hash2 || {} }, %{ $hash3 || {} });
    >
    > Or:
    >
    > %hash1 = (%{\%$hash2}, %{\%$hash3});


    I don't uderstand the last one, but I think I prefer this to
    "merge hashes and undefined values":

    %hash1=(defined $hash2 and defined $hash3) ? (%$hash2, %$hash3) : undef;
     
    farans, Jun 12, 2006
    #14
  15. farans wrote:

    > %hash1=(defined $hash2 and defined $hash3) ? (%$hash2, %$hash3) : undef;


    That is wrong in serveral ways.

    If both $hash2 and $hash3 are defined it will work correctly.

    If either $hash2 are $hash3 are undefined it will ignore the contents
    of the other one and set

    %hash1 = ( '' => undef)

    whilst emitting two warnings.
     
    Brian McCauley, Jun 13, 2006
    #15
  16. Derek Basch

    Brad Baxter Guest

    farans wrote:
    > On Fri, 09 Jun 2006 11:46:17 -0700, Brian McCauley wrote:
    >
    > > My preferred idiom is:
    > >
    > > %hash1 = (%{ $hash2 || {} }, %{ $hash3 || {} });
    > >
    > > Or:
    > >
    > > %hash1 = (%{\%$hash2}, %{\%$hash3});

    >
    > I don't uderstand the last one, ...


    >From perldoc perlref:

    6. References of the appropriate type can spring into
    existence if you dereference them in a context that
    assumes they exist.

    If $hash2 is undefined, you'll get a warning if you attempt
    to use it as a hashref, e.g.,

    >> perl -Mstrict -lwe 'my $hash2; print %$hash2'

    Can't use an undefined value as a HASH reference at -e line 1.

    But you do not get a warning if you dereference %$hash2;
    rather, a new hash is autovivified and a reference to it is
    stored in $hash2.

    >> perl -Mstrict -lwe 'my $hash2; print \%$hash2'

    HASH(0x229a4)

    Brian's
    > > %hash1 = (%{\%$hash2}, %{\%$hash3});


    takes advantage of this to supply an empty hash, sans
    warnings, if the reference begins undefined.

    -- Brad
     
    Brad Baxter, Jun 13, 2006
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Holness

    Hashes of Hashes via subs

    Ben Holness, Oct 5, 2003, in forum: Perl
    Replies:
    8
    Views:
    566
    Ben Holness
    Oct 8, 2003
  2. Giles Bowkett
    Replies:
    13
    Views:
    245
    Jacob Fugal
    Mar 15, 2007
  3. Andy Pipes
    Replies:
    6
    Views:
    130
    Andy Pipes
    Sep 30, 2008
  4. shenry
    Replies:
    14
    Views:
    235
    Rick DeNatale
    Nov 3, 2009
  5. Tim O'Donovan

    Hash of hashes, of hashes, of arrays of hashes

    Tim O'Donovan, Oct 27, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    214
Loading...

Share This Page