Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Re (tilly) 4: Calling subroutine in a package from other perl sub.

by tilly (Archbishop)
on Jan 17, 2001 at 07:48 UTC ( [id://52449]=note: print w/replies, xml ) Need Help??

in reply to Re: Re (tilly) 2: Calling subroutine in a package from other perl sub.
in thread Calling subroutine in a package from other perl sub.

First of all it is dangerous because the possibility for confusion is high. Sure, you may know to do it only when the called subroutine is unwilling to take arguments, but will the person who learns from your code know that?

As for your cute test function, it is really simple. Perl scalars are always references to data, not the actual data. So if you want to convert a list of scalars into a list, it is substantially more efficient to just make a list of pointers to the data than really copy. And that is what Perl does when passing data into a function. However when you assign in Perl you assign by value, not reference.

So your 3 variables coming in are really passed in by reference, so in test2 you are able to change the original variables (whether the originals were from a scalar or an array) through the references. (ie @_ is just a list of pointers back to the original variables.) In test1 you threw away the three references and then assigned to new variables. Well if you no longer have the three variables, then assigning to new ones won't change a thing.

And as you note this works just as well if you have the original argument list being 3 variables or an array with 3 things.

So the rule is that assignment is by value, and arguments are passed into functions by reference. You probably understand this correctly if you can puzzle out the following example:

($x, $y, $z) = 'x'..'z'; print "Original values.\n"; show_vals(); print "This rotates them.\n"; rotate($x, $y, $z); show_vals(); print "Why doesn't this?\n"; rotate_not($x, $y, $z); show_vals(); sub rotate { @_[-1..($#_-1)] = @_; } sub rotate_not { @_ = @_[-1..($#_-1)]; } sub show_vals { print "\$x: $x\n\$y: $y\n\$z: $z\n\n"; }
  • Comment on Re (tilly) 4: Calling subroutine in a package from other perl sub.
  • Download Code

Replies are listed 'Best First'.
Re: Re (tilly) 4: Calling subroutine in a package from other perl sub.
by zzspectrez (Hermit) on Jan 17, 2001 at 11:33 UTC

    Well, I would think it is because in sub rotate, you are assingning the data in @_ (x,y,z) to the aliases (references $x,$y,$z) indexed @_[-1..($#_-1]. However, in rotate_not, you are assinging the data (array slice) from @_[-1..($#_-1] to the array @_ and not the references. So you are overwriting the references to $x,$y,$z and not updating them.


      Exactly, assigning to a list means assigning to each element in that list. Assigning to an array means throwing away the existing array (if there is one) and creating a new one. Once again, Arrays are not lists. :-)

Log In?

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

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2024-04-16 23:15 GMT
Find Nodes?
    Voting Booth?

    No recent polls found