print statement creates key in hash with reference to empty array??

Discussion in 'Perl Misc' started by rhorizon74, Jan 31, 2006.

  1. rhorizon74

    rhorizon74 Guest

    In the code below the print val statement actually creates an key 'ABC'
    in the hash if it does not exist ( i wanted to print the value of the
    0th element in an array , the reference to which is stored in a hash
    with key 'ABC').

    Why should a print create a new key, shouldnt it just print undefined,
    and not create any new key.

    Thank you
    Code:

    use strict;
    use Data::Dumper;
    &main();

    sub main
    {
    my %a;
    my $aref = \%a;

    print "val: @{$aref->{ABC}}[0]\n";
    print Dumper($aref)."\n";
    }


    Output:
    val:
    $VAR1 = {
    'ABC' => []
    };
    rhorizon74, Jan 31, 2006
    #1
    1. Advertising

  2. "rhorizon74" <> wrote in
    news::

    > In the code below the print val statement actually creates an key
    > 'ABC' in the hash if it does not exist ( i wanted to print the value
    > of the 0th element in an array , the reference to which is stored in a
    > hash with key 'ABC').


    That's called autovivification (sp?) You can read Uri Guttman's article:

    http://www.sysarch.com/Perl/tutorials/autoviv.html

    If you want to avoid it, you need to use exists, and print only when the
    said element does exist.

    if( exists $hash{$key} ) {
    print "$hash{$key}\n";
    }

    > Why should a print create a new key, shouldnt it just print undefined,
    > and not create any new key.


    Why do you think so?

    > use strict;


    use warnings;

    missing.

    > use Data::Dumper;
    > &main();


    Do you know what '&' does here? If not, then don't use it.

    See

    perldoc perlsub


    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Jan 31, 2006
    #2
    1. Advertising

  3. rhorizon74 wrote:
    > In the code below the print val statement actually creates an key 'ABC'
    > in the hash if it does not exist ( i wanted to print the value of the
    > 0th element in an array , the reference to which is stored in a hash
    > with key 'ABC').
    >
    > Why should a print create a new key, shouldnt it just print undefined,
    > and not create any new key.
    >
    > Thank you
    > Code:
    >
    > use strict;
    > use Data::Dumper;
    > &main();
    >
    > sub main
    > {
    > my %a;
    > my $aref = \%a;
    >
    > print "val: @{$aref->{ABC}}[0]\n";
    > print Dumper($aref)."\n";
    > }
    >
    >
    > Output:
    > val:
    > $VAR1 = {
    > 'ABC' => []
    > };


    lookup autovivification.
    it_says_BALLS_on_your forehead, Jan 31, 2006
    #3
  4. rhorizon74

    rhorizon74 Guest

    Thanks for the help.

    That explains what is happening (i had used the exists approach to work
    around).
    But it does seem bogus that for a simple print statement i need to
    check each and every level. I havent seen too many languages do
    something like this (i may be wrong).
    But a print statement shouldnt really be creating any data.


    Thanks for the help though.
    rhorizon74, Jan 31, 2006
    #4
  5. "rhorizon74" <> wrote in news:1138725497.627908.102130
    @g44g2000cwa.googlegroups.com:

    > But it does seem bogus that for a simple print statement i need to
    > check each and every level. I havent seen too many languages do
    > something like this


    Please feel free to use one of the languages that behave in the way you
    think they should.

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Jan 31, 2006
    #5
  6. rhorizon74

    Dr.Ruud Guest

    A. Sinan Unur schreef:

    > if( exists $hash{$key} ) {
    > print "$hash{$key}\n";
    > }



    Hunting for alternatives:

    $ echo 'if( exists $hash{$key} ) { print "$hash($key)\n"; }' \
    | perl -MO=Deparse,-x7

    exists $hash{$key} and do {
    print "$hash($key)\n"
    };

    I don't know why the do-block is needed.


    $ echo 'print "$hash{$key}\n" if exists $hash{$key};' \
    | perl -MO=Deparse,-x7

    exists $hash{$key} and print "$hash{$key}\n";

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jan 31, 2006
    #6
  7. "Dr.Ruud" <> wrote in news:dro98o.vk.1
    @news.isolution.nl:

    > A. Sinan Unur schreef:
    >
    >> if( exists $hash{$key} ) {
    >> print "$hash{$key}\n";
    >> }

    >
    >
    > Hunting for alternatives:
    >
    > $ echo 'if( exists $hash{$key} ) { print "$hash($key)\n"; }' \


    Check out the missing curlies in the second hash access. Not that it
    changes anything.

    Sinan
    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Jan 31, 2006
    #7
  8. rhorizon74

    rhorizon74 Guest

    Just wanted to check if i was missing anything, Didnt think anybody
    woud get offended if i questioned a programming language, didnt realize
    that the perl way was set in stone.

    Thanks for your help anyways
    rhorizon74, Jan 31, 2006
    #8
  9. [ Please quote some context when you reply. ]

    "rhorizon74" <> wrote in news:1138729475.641979.180700
    @z14g2000cwz.googlegroups.com:

    > Just wanted to check if i was missing anything, Didnt think anybody
    > woud get offended if i questioned a programming language, didnt realize
    > that the perl way was set in stone.


    You did not offend anyone, at least not me.

    It was obvious that you had not read either the link I posted, or the
    documentation, and yet you were still opining about what should and should
    not be. With that attitude, I rather not read your posts.

    Sinan

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://mail.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
    A. Sinan Unur, Jan 31, 2006
    #9
  10. rhorizon74

    Uri Guttman Guest

    Re: print statement creates key in hash with reference to emptyarray??

    >>>>> "r" == rhorizon74 <> writes:

    r> Thanks for the help.
    r> That explains what is happening (i had used the exists approach to work
    r> around).
    r> But it does seem bogus that for a simple print statement i need to
    r> check each and every level. I havent seen too many languages do
    r> something like this (i may be wrong).
    r> But a print statement shouldnt really be creating any data.

    if you read my article (which sinan posted the url for) then you will
    learn more about autoviv and why it is like it is. and even calling
    exists will do the same thing (but that is being fixed in perl6). the
    win of autovivication is much greater then the loss of rare code like
    yours. if you didn't have it you would need to check each time you used a
    reference in structure and either assign a new one or use the existing
    one. that is massively ugly and clumsy (and i have seen newbies coding
    like that all the time).

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 31, 2006
    #10
  11. rhorizon74

    Ala Qumsieh Guest

    rhorizon74 wrote:
    > Thanks for the help.
    >
    > That explains what is happening (i had used the exists approach to work
    > around).
    > But it does seem bogus that for a simple print statement i need to
    > check each and every level. I havent seen too many languages do
    > something like this (i may be wrong).
    > But a print statement shouldnt really be creating any data.


    It is not the print(), it is the fact that you are trying to access the
    value of the ABC key. If hashes didn't autovivify, then you won't be
    able to do this:

    $hash{key1}{key2}{key3} = 'value';

    before you actually create all the keys explicitly:

    $hash{key1} = {};
    $hash{key1}{key2} = {};
    $hash{key1}{key2}{key3} = 'value';

    Autovivification is a Good Thing (tm).

    --Ala
    Ala Qumsieh, Jan 31, 2006
    #11
  12. rhorizon74

    Guest

    "rhorizon74" <> wrote:
    > Thanks for the help.
    >
    > That explains what is happening (i had used the exists approach to work
    > around).
    > But it does seem bogus that for a simple print statement i need to
    > check each and every level. I havent seen too many languages do
    > something like this (i may be wrong).


    Right. Many languages would just seg-fault, or perhaps corrupt memory
    and take down the entire system, instead.

    > But a print statement shouldnt really be creating any data.


    What should it do?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Jan 31, 2006
    #12
  13. rhorizon74

    rhorizon74 Guest

    Hi,

    The code i posted is just a sample, i was trying to understand exactly
    what was happening.

    The are a bunch of scenarios where a different module is supposed to
    build a hash, and my module needs to print the values. In which case
    for each level of nesting of a hash i will be forced to check if the
    node exists (starting with the outer hash and going onto the inner
    hash). With my limited exposure to perl i guess it seemed a bit
    diffcult to grasp.

    I do understand the efficiency it provides while creating a structure.

    I did check with a lot of colleagues some who were not exactly novices
    like me with way much more experience in perl and they too had come
    across this scenario (they grappled with this by adding checks for each
    level before printing the values) , but to be honest none with any
    exact knowlege of vivication. So it did seem like this problem was
    commonly faced by a lot of programmers.


    Thanks for the reply




    Uri Guttman wrote:
    > >>>>> "r" == rhorizon74 <> writes:

    >
    > r> Thanks for the help.
    > r> That explains what is happening (i had used the exists approach to work
    > r> around).
    > r> But it does seem bogus that for a simple print statement i need to
    > r> check each and every level. I havent seen too many languages do
    > r> something like this (i may be wrong).
    > r> But a print statement shouldnt really be creating any data.
    >
    > if you read my article (which sinan posted the url for) then you will
    > learn more about autoviv and why it is like it is. and even calling
    > exists will do the same thing (but that is being fixed in perl6). the
    > win of autovivication is much greater then the loss of rare code like
    > yours. if you didn't have it you would need to check each time you used a
    > reference in structure and either assign a new one or use the existing
    > one. that is massively ugly and clumsy (and i have seen newbies coding
    > like that all the time).
    >
    > uri
    >
    > --
    > Uri Guttman ------ -------- http://www.stemsystems.com
    > --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    > Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    rhorizon74, Jan 31, 2006
    #13
  14. rhorizon74

    rhorizon74 Guest

    Hi,

    Id rather have my program fail, most scripting languages would print an
    error (they would not seg-fault). That would be better than giving
    incorrect results.

    Moral of the story is i need to do an exists before i do anything with
    any hash related structure in perl.

    Thank you
    rhorizon74, Jan 31, 2006
    #14
  15. rhorizon74

    Ch Lamprecht Guest

    rhorizon74 wrote:
    > I havent seen too many languages do
    > something like this (i may be wrong).


    Who could tell this but you?

    Christoph
    --

    perl -e "print scalar reverse q//"
    Ch Lamprecht, Jan 31, 2006
    #15
  16. rhorizon74

    Uri Guttman Guest

    Re: print statement creates key in hash with reference to emptyarray??

    >>>>> "r" == rhorizon74 <> writes:

    r> The are a bunch of scenarios where a different module is supposed to
    r> build a hash, and my module needs to print the values. In which case
    r> for each level of nesting of a hash i will be forced to check if the
    r> node exists (starting with the outer hash and going onto the inner
    r> hash). With my limited exposure to perl i guess it seemed a bit
    r> diffcult to grasp.

    why are you printing lower levels and not the upper ones? try using
    data::dumper instead of rolling your own tree dumper.

    r> I did check with a lot of colleagues some who were not exactly novices
    r> like me with way much more experience in perl and they too had come
    r> across this scenario (they grappled with this by adding checks for each
    r> level before printing the values) , but to be honest none with any
    r> exact knowlege of vivication. So it did seem like this problem was
    r> commonly faced by a lot of programmers.

    it seems you still haven't read my article. have you? it has a sub which
    will do what you want so you don't have to reinvent it. i suggest you
    read it and also tell your colleagues to read it.

    r> Thanks for the reply

    no thanks for the top post with full quote of my email. have you read
    the group guidelines which are posted regularly?

    <snip of my entire quoted post>

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 31, 2006
    #16
  17. rhorizon74

    Uri Guttman Guest

    Re: print statement creates key in hash with reference to emptyarray??

    >>>>> "r" == rhorizon74 <> writes:

    r> Id rather have my program fail, most scripting languages would print an
    r> error (they would not seg-fault). That would be better than giving
    r> incorrect results.

    incorrect results? by whose definition are the results incorrect? you
    didn't read the docs to understand autoviv and assumed incorrect
    behavior. i lay that on you and not perl.

    r> Moral of the story is i need to do an exists before i do anything with
    r> any hash related structure in perl.

    the real moral is you haven't learned yet how to work with perl data
    structures. needing to print low level entries is very unusual. that
    leads me to suspect the quality of your structure's design. i have done
    many deep structures and never have come across this need. usually
    something at a higher level can be done so you don't need to directly
    access missing elements and thereby cause autoviv to happen.

    until you learn more about perl and its data structures you will be
    doomed to this poor style of design and coding.

    and read my article already. it was written specifically for you.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 31, 2006
    #17
  18. rhorizon74

    Dr.Ruud Guest

    Abigail:
    > Dr.Ruud:


    >> $ echo 'if( exists $hash{$key} ) { print "$hash($key)\n"; }' \
    >> | perl -MO=Deparse,-x7
    >>
    >> exists $hash{$key} and do {
    >> print "$hash($key)\n"
    >> };
    >>
    >> I don't know why the do-block is needed.

    >
    > Because the then part of an if statement is a block. 'do {}' turns a
    > block into an expression.


    I still don't see why it isn't 'cleaned up' further in the special case
    that the expression is one statement. As you can deduce, I assume that
    the "do{}" is never necessary around a single statement, that "()" is
    sufficient.

    I don't expect "()" for "do{}" to speed up anything, I just wondered a
    bit why that step isn't taken.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jan 31, 2006
    #18
  19. rhorizon74

    Anno Siegel Guest

    Dr.Ruud <> wrote in comp.lang.perl.misc:
    > Abigail:
    > > Dr.Ruud:

    >
    > >> $ echo 'if( exists $hash{$key} ) { print "$hash($key)\n"; }' \
    > >> | perl -MO=Deparse,-x7
    > >>
    > >> exists $hash{$key} and do {
    > >> print "$hash($key)\n"
    > >> };
    > >>
    > >> I don't know why the do-block is needed.

    > >
    > > Because the then part of an if statement is a block. 'do {}' turns a
    > > block into an expression.

    >
    > I still don't see why it isn't 'cleaned up' further in the special case
    > that the expression is one statement. As you can deduce, I assume that
    > the "do{}" is never necessary around a single statement, that "()" is
    > sufficient.


    No, the "do{}"s are necessary, there *must* be a statement in this place.
    It's just that the DWIM mechanism inserts them for you in many situations
    where little else would make sense. What deparse shows is what perl
    actually compiles.

    > I don't expect "()" for "do{}" to speed up anything, I just wondered a
    > bit why that step isn't taken.


    I don't see who could take that step. The Perl interpreter needs the
    "do{}"s, it cant discard them. Deparsing can't very well suppress them
    either, once they're there.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Feb 1, 2006
    #19
  20. rhorizon74

    Dr.Ruud Guest

    Anno Siegel schreef:
    > Dr.Ruud:
    >> Abigail:
    >>> Dr.Ruud:


    >>>> $ echo 'if( exists $hash{$key} ) { print "$hash($key)\n"; }' \
    >>>> | perl -MO=Deparse,-x7
    >>>>
    >>>> exists $hash{$key} and do {
    >>>> print "$hash($key)\n"
    >>>> };
    >>>>
    >>>> I don't know why the do-block is needed.
    >>>
    >>> Because the then part of an if statement is a block. 'do {}' turns a
    >>> block into an expression.

    >>
    >> I still don't see why it isn't 'cleaned up' further in the special
    >> case that the expression is one statement. As you can deduce, I
    >> assume that the "do{}" is never necessary around a single statement,
    >> that "()" is sufficient.

    >
    > No, the "do{}"s are necessary, there *must* be a statement in this
    > place. It's just that the DWIM mechanism inserts them for you in many
    > situations where little else would make sense. What deparse shows is
    > what perl actually compiles.


    From an earlier post:

    $ echo 'print "$hash{$key}\n" if exists $hash{$key};' \
    | perl -MO=Deparse,-x7

    exists $hash{$key} and print "$hash{$key}\n";

    That doesn't get a do{}.


    > Deparse can't very well suppress them either, once they're there.


    And I just wondered why not, for cases like this one.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Feb 1, 2006
    #20
    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:
    493
    red floyd
    Nov 10, 2011
  2. Une bévue
    Replies:
    5
    Views:
    140
    Une bévue
    Aug 10, 2006
  3. Srijayanth Sridhar
    Replies:
    19
    Views:
    596
    David A. Black
    Jul 2, 2008
  4. Antonio Quinonez
    Replies:
    2
    Views:
    154
    Antonio Quinonez
    Aug 14, 2003
  5. Steve

    hash reference as a hash key

    Steve, Sep 26, 2003, in forum: Perl Misc
    Replies:
    6
    Views:
    107
    Steve
    Sep 28, 2003
Loading...

Share This Page