|
| 8.10.3 Pass by Value vs. Pass by Reference |
|
Pass by value
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.
Pass by reference
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.
Differences from other languages
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.
|