In search of elegant code: Adding to a hash using (key => value) syntax

Discussion in 'Perl Misc' started by usenet@DavidFilmer.com, Jun 23, 2005.

  1. Guest

    I prefer this syntax when creating and populating hashes:

    my %hash = (
    'foo' => 'something',
    'bar' => 'else'
    );

    But suppose that, a little later, I want to add a few more keys/values.
    If it were a scalar I could add on using ".=" or if an array I could
    "push" onto it - but it seems that for a hash (if I want to keep my
    syntax consistent, which I do) I am forced to do something awkward
    like:

    %hash = (%hash, (
    'bax' => 'more',
    'baz' => 'stuff'
    ));

    It works, but... is there a more elegant way?
    , Jun 23, 2005
    #1
    1. Advertising

  2. Re: In search of elegant code: Adding to a hash using (key => value)syntax

    wrote:
    > I prefer this syntax when creating and populating hashes:
    >
    > my %hash = (
    > 'foo' => 'something',
    > 'bar' => 'else'
    > );
    >
    > But suppose that, a little later, I want to add a few more keys/values.
    > If it were a scalar I could add on using ".=" or if an array I could
    > "push" onto it - but it seems that for a hash (if I want to keep my
    > syntax consistent, which I do) I am forced to do something awkward
    > like:
    >
    > %hash = (%hash, (
    > 'bax' => 'more',
    > 'baz' => 'stuff'
    > ));
    >
    > It works, but... is there a more elegant way?


    That makes a temporary hash consisting of %hash, and the two new
    key-value pairs you want to add, and then assigns that to %hash. What is
    the point of engaging in such gross inefficiency?

    $hash{bax} = 'more';
    $hash{baz} = 'stuff;

    is elegant enough for me and easier to maintain. But, if you insist, why
    not use a hash slice?

    @hash{qw(bax baz)} = qw(more stuff);

    #!/usr/bin/perl

    use strict;
    use warnings;

    my %hash = (
    foo => 'something',
    bar => 'else',
    );

    @hash{qw(bax baz)} = qw(more stuff);

    print "$_ => $hash{$_}\n" for keys %hash;

    __END__

    Sinan
    A. Sinan Unur, Jun 23, 2005
    #2
    1. Advertising

  3. wrote:
    > I prefer this syntax when creating and populating hashes:
    >
    > my %hash = (
    > 'foo' => 'something',
    > 'bar' => 'else'
    > );
    >
    > But suppose that, a little later, I want to add a few more
    > keys/values. If it were a scalar I could add on using ".=" or if an
    > array I could "push" onto it - but it seems that for a hash (if I
    > want to keep my syntax consistent, which I do) I am forced to do
    > something awkward like:
    >
    > %hash = (%hash, (
    > 'bax' => 'more',
    > 'baz' => 'stuff'
    > ));
    >
    > It works, but... is there a more elegant way?


    What's wrong with a simple
    $hash{'bax'} = 'more';
    $hash{'baz'} = 'stuff';

    jue
    Jürgen Exner, Jun 23, 2005
    #3
  4. Steven Kuo Guest

    Re: In search of elegant code: Adding to a hash using (key => value)syntax

    On Wed, 22 Jun 2005 wrote:

    > I prefer this syntax when creating and populating hashes:
    >
    > my %hash = (
    > 'foo' => 'something',
    > 'bar' => 'else'
    > );
    >
    > But suppose that, a little later, I want to add a few more keys/values.
    > If it were a scalar I could add on using ".=" or if an array I could
    > "push" onto it - but it seems that for a hash (if I want to keep my
    > syntax consistent, which I do) I am forced to do something awkward
    > like:
    >
    > %hash = (%hash, (
    > 'bax' => 'more',
    > 'baz' => 'stuff'
    > ));
    >
    > It works, but... is there a more elegant way?






    If you insist on that adhering to that style, you could try a tied
    hash. You'll have to judge whether it's "elegant" -- to me it can
    also be a bit "dangerous" if one doesn't understand the implications
    of overwriting methods:

    #!/usr/bin/perl

    package CumulativeHash;
    require Tie::Hash;
    @ISA = ('Tie::StdHash');

    sub CLEAR
    {
    # does not clear previous entries
    }

    1;

    package main;

    use strict;
    use warnings;
    use Data::Dumper;

    my %hash;

    tie %hash, 'CumulativeHash';

    %hash = (
    foo => 'something',
    bar => 'else',
    );

    %hash = (
    'bax' => 'more',
    'baz' => 'stuff',
    );

    print Dumper \%hash;

    --
    Hope this helps,
    Steven
    Steven Kuo, Jun 23, 2005
    #4
  5. Guest

    >>> What is the point of engaging in such gross inefficiency?
    For the only reason that the syntax is more consistent with the
    statement that created the hash. But I never said it was elegant (or
    efficient).

    >>> $hash{bax} = 'more';
    >>> $hash{baz} = 'stuff;
    >>> is elegant enough for me and easier to maintain.

    It gets a bit repetitious to keep saying "$hash=..." if I want to add a
    dozen or more pairs. And it's not the same style of syntax that
    created the hash. But, yeah, it works, of course.

    >>> @hash{qw(bax baz)} = qw(more stuff);

    Yuck. Maintaining that across more than a few pairs would be awful.
    I'd rather be repetitious.

    It just seems like other data types have operators designed to append
    to them ('.=', push/unshift, '>>'). No such "append" operator exists
    for hashes. That's a bummer, IMHO.
    , Jun 23, 2005
    #5
  6. Guest

    oooooo, that's interesting (and a bit over my head - I need to study up
    a bit on what's going on here). Of course, it does seem like a big
    hammer for a small nail. It would be nice (IMHO) if Perl had an
    "append" operator for hashes, like it does for other types of data.
    , Jun 23, 2005
    #6
  7. <> wrote:

    > It just seems like other data types have operators designed to append
    > to them ('.=', push/unshift, '>>'). No such "append" operator exists
    > for hashes.



    Yes it does.

    The assignment operator (=) makes a hash get bigger, just as a
    push() makes an array get bigger.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jun 23, 2005
    #7
  8. John Bokma Guest

    "Tassilo v. Parseval" <> wrote:

    > push %hash, key1 => 1,
    > key2 => 2;


    Funny, you should have seen the post I just deleted :)

    I was including something like: it's silly to use push, since push assumes
    some order (I mean, what is unshift going to do, and pop, and shift). Also,
    one can overwrite keys.

    > Slicing is one way to do it, but then slicing works on arrays as well.
    > Hashes just lack a dedicated push operator which is partly due to their
    > slightly different nature (for instance there is no conceivable concept
    > for pushing a single value onto a hash since it has no tail after which
    > to append a datum).


    Ok, too fast again :-D

    --
    John Small Perl scripts: http://johnbokma.com/perl/
    Perl programmer available: http://castleamber.com/
    Happy Customers: http://castleamber.com/testimonials.html
    John Bokma, Jun 23, 2005
    #8
  9. Also sprach John Bokma:

    > "Tassilo v. Parseval" <> wrote:
    >
    >> push %hash, key1 => 1,
    >> key2 => 2;

    >
    > Funny, you should have seen the post I just deleted :)


    I haven't. :)

    > I was including something like: it's silly to use push, since push assumes
    > some order (I mean, what is unshift going to do, and pop, and shift). Also,
    > one can overwrite keys.


    Yes, at some point the analogy stops working. OTOH, 'pop' and 'shift'
    could be made synonyms to 'delete'. Whereas 'unshift' would necessarily
    be the same as 'push'.

    Tassilo
    --
    use bigint;
    $n=71423350343770280161397026330337371139054411854220053437565440;
    $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
    Tassilo v. Parseval, Jun 23, 2005
    #9
  10. Also sprach Tad McClellan:

    > <> wrote:
    >
    >> It just seems like other data types have operators designed to append
    >> to them ('.=', push/unshift, '>>'). No such "append" operator exists
    >> for hashes.

    >
    >
    > Yes it does.
    >
    > The assignment operator (=) makes a hash get bigger, just as a
    > push() makes an array get bigger.


    Only on per-key basis, not on the hash as a whole. It's not the same
    thing as push() at all. There is no reason why push couldn't be extended
    to work on hashes, too:

    push %hash, key1 => 1,
    key2 => 2;

    Slicing is one way to do it, but then slicing works on arrays as well.
    Hashes just lack a dedicated push operator which is partly due to their
    slightly different nature (for instance there is no conceivable concept
    for pushing a single value onto a hash since it has no tail after which
    to append a datum).

    Tassilo
    --
    use bigint;
    $n=71423350343770280161397026330337371139054411854220053437565440;
    $m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);
    Tassilo v. Parseval, Jun 23, 2005
    #10
  11. Tassilo v. Parseval <> kirjoitti 23.06.2005:
    > Also sprach John Bokma:
    >> "Tassilo v. Parseval" <> wrote:
    >>
    >>> push %hash, key1 => 1,
    >>> key2 => 2;
    >>>

    >> I was including something like: it's silly to use push, since push assumes
    >> some order (I mean, what is unshift going to do, and pop, and shift). Also,
    >> one can overwrite keys.

    >
    > Yes, at some point the analogy stops working. OTOH, 'pop' and 'shift'
    > could be made synonyms to 'delete'. Whereas 'unshift' would necessarily
    > be the same as 'push'.


    No, shift and pop should be equivalent to:

    sub pop_hash (\%) {
    my ($hash) = @_;
    keys %$hash; # reset iterator!
    my @pair = each %$hash or return;
    delete $hash->{$pair[0]};
    return @pair;
    }

    Ideally the implementation wouldn't need to use the internal hash
    iterator at all. Proper behavior in scalar context I'll leave for
    others to decide.

    --
    Ilmari Karonen
    To reply by e-mail, please replace ".invalid" with ".net" in address.
    Ilmari Karonen, Jun 23, 2005
    #11
  12. Re: In search of elegant code: Adding to a hash using (key => value)syntax

    wrote:
    > I prefer this syntax when creating and populating hashes:
    >
    > my %hash = (
    > 'foo' => 'something',
    > 'bar' => 'else'
    > );
    >
    > But suppose that, a little later, I want to add a few more keys/values.
    > If it were a scalar I could add on using ".=" or if an array I could
    > "push" onto it - but it seems that for a hash (if I want to keep my
    > syntax consistent, which I do) I am forced to do something awkward
    > like:
    >
    > %hash = (%hash, (
    > 'bax' => 'more',
    > 'baz' => 'stuff'
    > ));
    >
    > It works, but... is there a more elegant way?


    Well just in terms of formatting I'd say it's more elegant and consistant as

    %hash = (
    %hash,
    'bax' => 'more',
    'baz' => 'stuff',
    );
    Brian McCauley, Jun 25, 2005
    #12
  13. Guest

    Brian McCauley <> wrote:
    Subject: Perl & academia, maybe OT [was Re: In search of elegant code: Adding to a hash using (key => value) syntax]
    Newsgroups: comp.lang.perl.misc
    References: <> <d9j3vd$8fk$>

    Brian McCauley <> wrote:
    [something not related to my follow-up]

    Brian, I notice that you are posting from Birmingham University...
    interestingly I popped into the bookshop there a couple of days
    ago and see that the stock has not improved since my days at the
    university. Out of curiosity I looked to see if there were any Perl
    books - not a single one. Now, I do put this down to the bookshop
    having a poor selection of books - let's face it students have
    little enough money as it is to spend on beer let alone books. But
    I was just wondering out of idle curiosity if any courses in Perl
    are taught?

    Axel
    , Jun 25, 2005
    #13
    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. rp
    Replies:
    1
    Views:
    500
    red floyd
    Nov 10, 2011
  2. Une bévue
    Replies:
    5
    Views:
    141
    Une bévue
    Aug 10, 2006
  3. Antonio Quinonez
    Replies:
    2
    Views:
    156
    Antonio Quinonez
    Aug 14, 2003
  4. David Filmer
    Replies:
    9
    Views:
    105
  5. Ralf Baerwaldt
    Replies:
    1
    Views:
    123
    Paul Lalli
    Jul 20, 2004
Loading...

Share This Page