8.10.3 Pass by Value vs. Pass by Reference | |
When a function is called, its parameters receive a distinct copy of the caller's arguments, as if the parameters were assigned from the arguments . This method is known as pass by value . A script can thus call a function with the assurance that its own local variables cannot be modified by the function, even if the internals of the function are unknown:
<A NAME=sec2hms num> <$h = ($num / 3600)> <$num = ($num - $h * 3600)> <$m = ($num / 60)> <$s = ($num - $m * 60)> </A> <A NAME=main> <$num = 7300> <sec2hms num=$num> $num seconds is: $h hours $m minutes and $s seconds </A> |
Here we call sec2hms to translate a cumulative seconds count to hours/minutes/seconds ($h /$m /$s ). While doing this, sec2hms modifies its $num parameter. Since it was passed by value in main , main 's value of $num - the global one - is unchanged on return.
Sometimes it is desirable to let a function modify its caller's arguments, however. For example, the function might return several distinct variables instead of just $ret , as in our example above, which sets $h , $m and $s as well. Returning these through global variables is untidy: in a larger application we might forget just what variables sec2hms changes, and accidentally erase values saved by another function.
If a function's parameters are passed from variables with $& instead of $ in front, changes to parameters will affect the caller's arguments as well, for they are the same variable. This is called pass by reference . For example:
<A NAME=sec2hms num h m s> <$h = ($num / 3600)> <$num = ($num - $h * 3600)> <$m = ($num / 60)> <$s = ($num - $m * 60)> </A> <A NAME=main> <LOCAL hour min sec> <$num = 7300> <sec2hms num=$num h=$&hour m=$&min s=$&sec> $num seconds is: $hour hours $min minutes and $sec seconds </A> |
Here we've modified sec2hms to take another 3 parameters, the hour/minute/seconds we're going to return. We pass them by reference in main . Now when $h is assigned in sec2hms , it's actually modifying main 's $hour variable; similarly, $m is tied to $min and $s to $sec . In this way, we completely self-contain sec2hms : it does not modify any variables that are not passed to it, only its parameters. It has no side effects.
Only script and library functions can be called with pass-by-reference arguments; all other functions are called pass-by-value.
Unlike other languages, it is up to the caller to determine which method is used, not the function. This makes it easier to see whether arguments can be modified - the call syntax shows it, not the function declaration which may be buried in another file. It also gives callers control over their arguments, not the function writer.
Back: Function Parameters | Next: Common Tasks in Vortex |