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.

Back: Function Parameters Next: Common Tasks in Vortex
Copyright © 2024 Thunderstone Software LLC. All rights reserved.