References - problem understanding them

Discussion in 'Perl Misc' started by Jürgen Herz, Aug 20, 2006.

  1. Jürgen Herz

    Jürgen Herz Guest

    Hi,

    currently I'm trying to understand references. I've read perltut.pod and
    perlreftut.pod but still don't know why does this works:

    my $content = test();
    for (keys %{$content})
    { print "$_: ",$content->{$_},"\n" }

    sub test
    {
    my %content = (one => "eins", two => "zwei");
    return \%content;
    }

    I'd expect accessing the hash in main doesn't work because it doesn't
    exist anymore outside of test(), just the pointer to that gone hash.

    I guess I'm wrong in understanding references as pointers like they are
    in C. But what are they then?

    Regards,
    Jürgen
    Jürgen Herz, Aug 20, 2006
    #1
    1. Advertising

  2. Jürgen Herz

    David Squire Guest

    Jürgen Herz wrote:
    > Hi,
    >
    > currently I'm trying to understand references. I've read perltut.pod and
    > perlreftut.pod but still don't know why does this works:


    missing:

    use strict;
    use warnings;

    (though in fact your code is fine w.r.t. both of them)

    > my $content = test();
    > for (keys %{$content})
    > { print "$_: ",$content->{$_},"\n" }
    >
    > sub test
    > {
    > my %content = (one => "eins", two => "zwei");
    > return \%content;
    > }
    >
    > I'd expect accessing the hash in main doesn't work because it doesn't
    > exist anymore outside of test(), just the pointer to that gone hash.


    OK. I take it you were expecting this code *not* to work, and are
    surprised that it did? That's a change from most questions around here :)

    > I guess I'm wrong in understanding references as pointers like they are
    > in C. But what are they then?


    I don't know the details of how references are implemented in Perl, but
    they are more than just a bare pointer (i.e. integer) like that you
    would get in C.

    The reason that your example works is that Perl is a garbage-collected
    language (unlike C), and many garbage-collected languages maintain
    counts of references to chunks of memory that are allocated. The memory
    is only freed when the reference count goes to zero. Since your sub
    returns a reference to the hash created within it, that hash sticks
    around so long as the reference exists.


    DS
    David Squire, Aug 21, 2006
    #2
    1. Advertising

  3. Jürgen Herz wrote:
    > Hi,
    >
    > currently I'm trying to understand references. I've read perltut.pod
    > and perlreftut.pod but still don't know why does this works:
    >
    > my $content = test();
    > for (keys %{$content})
    > { print "$_: ",$content->{$_},"\n" }
    >
    > sub test
    > {
    > my %content = (one => "eins", two => "zwei");
    > return \%content;
    > }
    >
    > I'd expect accessing the hash in main doesn't work because it doesn't
    > exist anymore outside of test(), just the pointer to that gone hash.


    What is gone after the sub is the _name_ %content. But the object behind
    that name still exists. There is still a reference pointing to the object
    and therefore the perl garbage collector does not recycle that object yet.

    > I guess I'm wrong in understanding references as pointers like they
    > are in C. But what are they then?


    They are references. And they have very little in common with pointers in C.
    Actually they are much easier to understand if you don't have the burden of
    previous C knowledge.

    jue
    Jürgen Exner, Aug 21, 2006
    #3
  4. Jürgen Herz

    Guest

    Jürgen_Herz <> wrote:
    > Hi,
    >
    > currently I'm trying to understand references. I've read perltut.pod and


    AFAIK, there is no perltut. Have you read perlref?

    > perlreftut.pod but still don't know why does this works:
    >
    > my $content = test();
    > for (keys %{$content})
    > { print "$_: ",$content->{$_},"\n" }
    >
    > sub test
    > {
    > my %content = (one => "eins", two => "zwei");
    > return \%content;
    > }
    >
    > I'd expect accessing the hash in main doesn't work because it doesn't
    > exist anymore outside of test(), just the pointer to that gone hash.


    Garbage collection is explained in the 2nd paragraph (v.5.8.8) of
    the "description" section of perlref.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Aug 21, 2006
    #4
  5. Jürgen Herz

    Klaus Guest

    Jürgen Herz wrote:
    > Hi,
    >
    > currently I'm trying to understand references. I've read perltut.pod and
    > perlreftut.pod but still don't know why does this works:
    >
    > my $content = test();
    > for (keys %{$content})
    > { print "$_: ",$content->{$_},"\n" }
    >
    > sub test
    > {
    > my %content = (one => "eins", two => "zwei");
    > return \%content;
    > }
    >
    > I'd expect accessing the hash in main doesn't work because it doesn't
    > exist anymore outside of test(), just the pointer to that gone hash.
    >
    > I guess I'm wrong in understanding references as pointers like they are
    > in C. But what are they then?


    There is some explanation in perlsub (although it is not obvious to
    find)

    -------------------------------------------------
    "Persistent Private Variables"

    Just because a lexical variable is lexically (also called statically)
    scoped to its enclosing block, eval, or do FILE, this doesn't mean that
    within a function it works like a C static. It normally works more like
    a C auto, but with implicit garbage collection.

    Unlike local variables in C or C++, Perl's lexical variables don't
    necessarily get recycled just because their scope has exited. If
    something more permanent is still aware of the lexical, it will stick
    around. So long as something else references a lexical, that lexical
    won't be freed--which is as it should be. You wouldn't want memory
    being free until you were done using it, or kept around once you were
    done. Automatic garbage collection takes care of this for you.

    [...]
    -------------------------------------------------
    Klaus, Aug 21, 2006
    #5
  6. Jürgen Herz wrote:

    > I'd expect accessing the hash in main doesn't work because it doesn't
    > exist anymore outside of test(), just the pointer to that gone hash.
    >
    > I guess I'm wrong in understanding references as pointers like they are
    > in C. But what are they then?


    People will often tell you C pointers and Perl references aren't the
    same thing in response to a question like that, but IMHO that's a
    terrible thing to tell a C programmer.

    In reality they're the same thing, but what you should not do is
    confuse lexically scoped variables with stack-allocated variables in C.
    You essentially have no access to the stack at all in Perl. The "Perl
    stack" is malloced memory, and items allocated on it are freed when
    they are no longer referenced. By creating a reference to your
    lexically scoped hash, you asked Perl not to release it.

    Hope that helps, one C programmer to another.
    Aaron Sherman, Aug 21, 2006
    #6
  7. Jürgen Herz

    Dr.Ruud Guest

    xhoster: schreef:
    > Jürgen_Herz:


    >> currently I'm trying to understand references.
    >> I've read perltut.pod and

    >
    > AFAIK, there is no perltut.


    ISHM perlreftut.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Aug 21, 2006
    #7
  8. Jürgen Herz

    Matt Garrish Guest

    Dr.Ruud wrote:

    > xhoster: schreef:
    > > Jürgen_Herz:

    >
    > >> currently I'm trying to understand references.
    > >> I've read perltut.pod and

    > >
    > > AFAIK, there is no perltut.

    >
    > ISHM perlreftut.
    >


    ITYM ITHM? Or is this some concoction of "I'm Sure He Meant", which is
    just a guess after staring at for some time. It would be so much easier
    to just write what is intended.

    (Not to single you out on this particular pet peeve of mine except for
    the fact I couldn't decipher this one, but it is annoying in general to
    have to look these things up when one isn't hip to the comings and
    goings of acronyms.)

    Matt
    Matt Garrish, Aug 21, 2006
    #8
  9. Jürgen Herz

    Jürgen Herz Guest

    wrote:
    > Jürgen_Herz <> wrote:
    >> currently I'm trying to understand references. I've read perltut.pod and

    >
    > AFAIK, there is no perltut. Have you read perlref?


    I meant perlref. Yes, I've read it, but not really understood - as I fear.


    >> I'd expect accessing the hash in main doesn't work because it doesn't
    >> exist anymore outside of test(), just the pointer to that gone hash.

    >
    > Garbage collection is explained in the 2nd paragraph (v.5.8.8) of
    > the "description" section of perlref.


    Hm, explained - yes and no. Now I know how it works, I understand that
    paragraph - but not before. And still I think "automatically freeing the
    thing referred to when its reference count goes to zero" doesn't
    implicate it's *not* freed as long a reference to it exists.

    Thank you,
    Jürgen
    Jürgen Herz, Aug 21, 2006
    #9
  10. Jürgen Herz

    Jürgen Herz Guest

    David Squire wrote:
    > Jürgen Herz wrote:
    >> Hi,
    >>
    >> currently I'm trying to understand references. I've read perltut.pod and
    >> perlreftut.pod but still don't know why does this works:

    >
    > missing:
    >
    > use strict;
    > use warnings;


    No, not missing. I just let them out here in order to make the example
    shorter. I guess that was to well-meant.

    > OK. I take it you were expecting this code *not* to work, and are
    > surprised that it did? That's a change from most questions around here :)


    :)
    Yes, you're right. I often go the way of writing code that I'd expect
    not to work in order to be sure I've understood all aspects. Which I
    didn't here.

    > The reason that your example works is that Perl is a garbage-collected
    > language (unlike C), and many garbage-collected languages maintain
    > counts of references to chunks of memory that are allocated. The memory
    > is only freed when the reference count goes to zero. Since your sub
    > returns a reference to the hash created within it, that hash sticks
    > around so long as the reference exists.


    Thank you, now I see why it works like it does.

    Regards,
    Jürgen
    Jürgen Herz, Aug 21, 2006
    #10
  11. Jürgen Herz

    Jürgen Herz Guest

    Klaus wrote:

    > There is some explanation in perlsub (although it is not obvious to
    > find)
    >
    > [...]


    Uh yes, that's the answer to why that works.

    But I still have a bad feeling doing that. So is it considered good (or
    bad) style relying on this behaviour? Though it seems to be guaranteed
    and should always work, maybe it's on some "List of things better not to
    do" because of something like code comprehensibility.

    Thank you,
    Jürgen
    Jürgen Herz, Aug 21, 2006
    #11
  12. Jürgen Herz

    Jürgen Herz Guest

    Aaron Sherman wrote:

    > In reality they're the same thing, but what you should not do is
    > confuse lexically scoped variables with stack-allocated variables in C.
    > You essentially have no access to the stack at all in Perl. The "Perl
    > stack" is malloced memory, and items allocated on it are freed when
    > they are no longer referenced. By creating a reference to your
    > lexically scoped hash, you asked Perl not to release it.
    >
    > Hope that helps, one C programmer to another.


    Indeed that helped. Not references itself are different but the system
    of variable allocation in Perl at all.

    Thanks,
    Jürgen
    Jürgen Herz, Aug 21, 2006
    #12
  13. Jürgen Herz

    Dr.Ruud Guest

    Matt Garrish schreef:
    > Dr.Ruud:
    >> xhoster:
    >>> Jürgen_Herz:


    >>>> currently I'm trying to understand references.
    >>>> I've read perltut.pod and
    >>>
    >>> AFAIK, there is no perltut.

    >>
    >> ISHM perlreftut.

    >
    > ITYM ITHM? Or is this some concoction of "I'm Sure He Meant", which is
    > just a guess after staring at for some time. It would be so much
    > easier to just write what is intended.


    It was meant as funny. Not everybody knows even what 'AFAIK' means. My
    'S' was 'suppose(d)'.


    > (Not to single you out on this particular pet peeve of mine except for
    > the fact I couldn't decipher this one, but it is annoying in general
    > to have to look these things up when one isn't hip to the comings and
    > goings of acronyms.)



    It's OK. (old knowledge?)

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Aug 21, 2006
    #13
  14. Jürgen Herz

    Klaus Guest

    Jürgen Herz wrote:
    > Klaus wrote:
    >
    > > There is some explanation in perlsub (although it is not obvious to
    > > find)
    > >
    > > [...]

    >
    > Uh yes, that's the answer to why that works.
    >
    > But I still have a bad feeling doing that.


    I can understand this, I had the same bad feeling when I started perl
    programming. But after several years, I now have a good feeling about
    that.

    > So is it considered good (or bad) style relying on this behaviour?


    Personally, I consider this a good style.

    > Though it seems to be guaranteed and should always work,


    There are thousands of CPAN modules which rely heavily on garbage
    collection, and they work fine...

    ....but yes, the garbage collector itself is written by humans, and
    humans can make mistakes, but I believe that the human who wrote the
    garbage collector makes much less mistakes than I would make, if I
    wrote my own code to collect garbage.

    > maybe it's on some "List of things better not to do" because of
    > something like code comprehensibility.


    Not having to worry about garbage collection in the actual code
    improves code comprehensibility.
    Klaus, Aug 21, 2006
    #14
  15. Jürgen Herz

    -berlin.de Guest

    Klaus <> wrote in comp.lang.perl.misc:
    > Jürgen Herz wrote:


    [...]

    > ...but yes, the garbage collector itself is written by humans, and
    > humans can make mistakes, but I believe that the human who wrote the
    > garbage collector makes much less mistakes than I would make, if I
    > wrote my own code to collect garbage.


    The garbage collector proper is relatively safe, it's a compact bit
    of code that's well debugged. It's rather the maintenance of the
    refcount that's error-prone. That happens all over the perl code
    (and in XS modules) whenever the default behavior isn't good enough,
    which is often. Symptoms are memory leaks when the refcount is too
    high and segfaults or entirely bizarre behavior when it is too low.
    This must be carefully debugged if perl is to keep its promise that
    references are automatically collected and never dangle.

    Anno
    -berlin.de, Aug 21, 2006
    #15
  16. Jürgen Herz wrote:
    > Aaron Sherman wrote:
    >
    >> In reality they're the same thing, but what you should not do is
    >> confuse lexically scoped variables with stack-allocated variables in
    >> C. You essentially have no access to the stack at all in Perl. The
    >> "Perl stack" is malloced memory, and items allocated on it are freed
    >> when they are no longer referenced. By creating a reference to your
    >> lexically scoped hash, you asked Perl not to release it.
    >>
    >> Hope that helps, one C programmer to another.

    >
    > Indeed that helped. Not references itself are different


    Sorry, but I strongly disagree. Pointers in C are memory addresses,
    something that otherwise you find in assembler. You can manipulate them, you
    can add or subtract to the address, etc, etc.
    A reference in Perl is an _abstract_, well, reference to one concrete
    object. You cannot change it, you cannot manipulate it, you cannot create it
    or destroy it. On an implementation level it may be implemented as a C
    pointer, but it could just as well be an index into some variable list or
    whatever. As a Perl programmer you don't know and you don't care.

    > but the system
    > of variable allocation in Perl at all.


    Not really. Perl and C are actually quite similar. Had you said that
    _memory_ allocation and management is different, then yes, because C forces
    the programmer to implement memory management manually while Perl does it
    automatically. There is not new(), malloc(), or free() in Perl.

    jue
    Jürgen Exner, Aug 21, 2006
    #16
  17. Jürgen Herz

    Guest

    Jürgen_Herz <> wrote:
    > Klaus wrote:
    >
    > > There is some explanation in perlsub (although it is not obvious to
    > > find)
    > >
    > > [...]

    >
    > Uh yes, that's the answer to why that works.
    >
    > But I still have a bad feeling doing that. So is it considered good (or
    > bad) style relying on this behaviour?


    It is excellent style to rely on it. And it isn't like there is a choice.
    Pure Perl has no user-accessible malloc or free.


    > Though it seems to be guaranteed
    > and should always work, maybe it's on some "List of things better not to
    > do" because of something like code comprehensibility.


    What alternative would you propose?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Aug 21, 2006
    #17
  18. Jürgen Herz

    Jürgen Herz Guest

    wrote:

    >> Though it seems to be guaranteed
    >> and should always work, maybe it's on some "List of things better not to
    >> do" because of something like code comprehensibility.

    >
    > What alternative would you propose?


    I'm far from proposing anything. But using plain hash would also work at
    least in my example:

    my %content2 = test2();
    for (keys %content2)
    { print "$_: ",$content2{$_},"\n" }

    sub test2
    {
    my %content2 = (one => "eins", two => "zwei");
    return %content2;
    }

    Jürgen
    Jürgen Herz, Aug 21, 2006
    #18
  19. Jürgen Herz

    David Squire Guest

    Jürgen Herz wrote:
    > wrote:
    >
    >>> Though it seems to be guaranteed
    >>> and should always work, maybe it's on some "List of things better not to
    >>> do" because of something like code comprehensibility.

    >> What alternative would you propose?

    >
    > I'm far from proposing anything. But using plain hash would also work at
    > least in my example:
    >
    > my %content2 = test2();
    > for (keys %content2)
    > { print "$_: ",$content2{$_},"\n" }
    >
    > sub test2
    > {
    > my %content2 = (one => "eins", two => "zwei");
    > return %content2;
    > }



    Sure, this will work, but the entire hash gets copied when the sub
    returns. For large data structures this can be very inefficient. Passing
    around references is much more memory and time efficient for large and
    complex data structures.


    DS
    David Squire, Aug 21, 2006
    #19
  20. Jürgen Herz

    Uri Guttman Guest

    >>>>> "x" == xhoster <> writes:

    >> But I still have a bad feeling doing that. So is it considered good (or
    >> bad) style relying on this behaviour?


    x> It is excellent style to rely on it. And it isn't like there is a choice.
    x> Pure Perl has no user-accessible malloc or free.


    >> Though it seems to be guaranteed
    >> and should always work, maybe it's on some "List of things better not to
    >> do" because of something like code comprehensibility.


    x> What alternative would you propose?

    there is another style choice. returning a ref to a lexical array/hash
    may be confusing but returning an anon array/hash could be less
    confusing. so instead of

    my @array ;

    return \@array ;

    do

    my $aref = [] ;

    return $aref ;

    they do the exact same thing but it is clearer code IMO to explicitly
    create and return an anon array (or hash). not that i haven't done the
    former in some cases but i lean to doing the latter.

    the only downside to the $aref version would be how you stuff it. you
    have to deref it with ->[] or @{} where in the former case you can do
    the slightly simpler direct access to the array.

    so here is the choice: cleaner looking return of a ref vs cleaner
    access to the array in the sub.

    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, Aug 21, 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. Anonieko

    HttpHandlers - Learn Them. Use Them.

    Anonieko, Jun 15, 2006, in forum: ASP .Net
    Replies:
    5
    Views:
    507
    tdavisjr
    Jun 16, 2006
  2. JohnJSal
    Replies:
    13
    Views:
    416
    Dennis Lee Bieber
    Nov 3, 2006
  3. Replies:
    9
    Views:
    323
    Dave Rahardja
    Mar 16, 2007
  4. why the lucky stiff
    Replies:
    5
    Views:
    134
    why the lucky stiff
    Sep 22, 2004
  5. David M. Karr
    Replies:
    1
    Views:
    80
    Jim Ley
    Jan 3, 2004
Loading...

Share This Page