Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: Pass array, then clear

by Anonymous Monk
on Jan 16, 2018 at 17:40 UTC ( #1207362=note: print w/replies, xml ) Need Help??


in reply to Re: Pass array, then clear
in thread Pass array, then clear

I think my problem with all of this was a misunderstanding of the mechanics of calls to subroutines. I did not suspect that the subroutine made a copy of the memory address. I figured that by passing in a reference, then whatever I did to the reference would reflect the new state of the reference. I don't think this was an unreasonable expectation. If the mechanics were different, well it would be different. Suppose the variable passing used some sort of "slot based" mechanism where the caller/sub could agree on variables (references) in and their value (slot) on return? That could work. Maybe it's dumb, but I don't think it's as off the wall as expecting houses to be empty given a new key:)

Replies are listed 'Best First'.
Re^3: Pass array, then clear
by Crackers2 (Parson) on Jan 16, 2018 at 18:27 UTC
    I did not suspect that the subroutine made a copy of the memory address

    It doesn't. You do, with the my($data) = @_; snippet. If you directly manipulate the argument, it works as you expect:

    sub clear_it { $_[0] = []; }

    Because you're then working on the original reference, not on the copy you made.

      Thank you, I did not realize that!
      This reply really brings it home for me. Light coming on strongly (or is it just the flames of the reference burnage?). I now see the error of my ways.
Re^3: Pass array, then clear
by ikegami (Pope) on Jan 17, 2018 at 05:03 UTC

    I did not suspect that the subroutine made a copy of the memory address.

    It doesn't (though you did in the first line of the sub).

    I figured that by passing in a reference, then whatever I did to the reference would reflect the new state of the reference.

    You didn't do anything to the reference. (You changed the value of $data.)

    Also, there isn't really anything you can do to a reference. You can't change a reference any more than you can change 5.

    Suppose the variable passing used some sort of "slot based" mechanism where the caller/sub could agree on variables (references) in and their value (slot) on return?

    That is what happens. You didn't change any of the slots (elements of @_).

Re^3: Pass array, then clear
by pryrt (Monsignor) on Jan 17, 2018 at 15:06 UTC
    I did not suspect that the subroutine made a copy of the memory address.

    ikegami++ just responded excellently, but I liked the earlier house key analogy, so want to expand on that.

    $outside_data = ['a','b']; clear_it($outside_data); sub clear_it {
    Grab a key unlocking a house containing two rooms; one room contains 'a', the other contains 'b'. Put that key in pocket#0, with pockets#1..n all empty
    my($data)=@_;Grab the contents of pocket#0 (the key), create a duplicate, and put that duplicate in my pants pocket that I've named $data; ignore the contents of all other coat pockets (for now).
    $data = [];Create a new key to an empty house. I want to put the new key into my pants pocket named $data, but that pants pocket was already full. Thus, empty the pocket and lose track of the duplicate key that I used to have in there (but I've still got the original key in my coat pocket#0). Now that my $data pocket is empty, it has room to hold the new key, so I put that key in.
    }At this point, I actually empty the pants pockets and throw away the key to the new house. At some point, the perl garbage collectors will see a house with no keys, and demolish it, freeing up the property for future use. We don't really notice, because the garbage collectors work at night when no one is watching, and we're all waiting with baited breath to look inside a house.
    print "size = ", scalar(@$outside_data)Take the key out of my coat pocket#0, unlock the house, and look at how many rooms are in the house it unlocks. We see 2 rooms, because it's still the original key, and we've never done anything to the inside of the original house.

    alternately:

    $outside_data = ['a','b']; clear_it($outside_data); sub clear_it {
    (same as above)
    my($data)=@_;(same as above)
    @$data = ...Use the duplicate key that's in my $data pocket to unlock the door to the house.
    ... = ();Once inside the house, demolish everything inside that house and throw out all the rubble. It's the same house, it's just now empty inside. Any key that fits the house will still unlock the house.
    }As before, I still throw away the $data key; it was a duplicate, and I still have the key in my coat pocket#0.
    print "size = ", scalar(@$outside_data)Take the key out of my coat pocket#0, unlock the house, and look inside. We see the now-empty house, so it will say 0, because it's still the original house, which we "renovated".

    I hope this helps paint a mental picture of what's going on.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1207362]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2021-12-03 06:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    R or B?



    Results (28 votes). Check out past polls.

    Notices?