Programming |
Using Function Handles with Nested Functions
Every function has a certain scope, that is, a certain range of other functions to which it is visible. A function's scope determines which other functions can call it. You can call a function that is out of scope by providing an alternative means of access to it in the form of a function handle. (The function handle, however, must be within the scope of its related function when you construct the handle.) Any function that has access to a function handle can call the function with which the handle is associated.
Note Although you can call an out of scope function by means of a function handle, the handle itself must be within the scope of its related function at the time it is constructed. |
The section on Calling Nested Functions defines the scope of a nested function. As with other types of functions, you can make a nested function visible beyond its normal scope with a function handle. The following function getCubeHandle
constructs a handle for nested function findCube
and returns its handle, h
, to the caller. The @
sign placed before a function name (e.g., @findCube
) is the MATLAB operator that constructs a handle for that function:
function h = getCubeHandle h = @findCube; % Function handle constructor function cube = findCube(X) % Nested function cube = X .^ 3; end end
Call getCubeHandle
to obtain the function handle to the nested function findCube
. Assign the function handle value returned by getCubeHandle
to an output variable, cubeIt
in this case:
You can now use this variable as a means of calling findCube
from outside of its M-file:
Function Handles and Nested Function Variables
One characteristic of nested functions that makes them different from other MATLAB functions is that they can share nonglobal variables with certain other functions within the same M-file. A nested function nFun
can share variables with any outer function that contains nFun
, and with any function nested within nFun
. This characteristic has an impact on how certain variables are stored when you construct a handle for a nested function.
Defining Variables When Calling Via Function Handle. The example below shows a primary function getHandle
that returns a function handle for the nested function nestFun
. The nestFun
function uses three different types of variables. The VLoc
variable is local to the nested function, VInp
is passed in when the nested function is called, and VExt
is defined by the outer function:
function h = getHandle(X)
h = @nestFun
;
VExt = someFun(X);
function nestFun(VInp)
VLoc = 173.5;
doSomeTask(VInp, VLoc, VExt);
end
end
As with any function, when you call nestFun
, you must ensure that you supply the values for any variables it uses. This is a straightforward matter when calling the nested function directly (that is, calling it from getHandle
). VLoc
has a value assigned to it within nestFun
, VInp
has its value passed in, and VExt
acquires its value from the workspace it shares with getHandle
.
However, when you call nestFun
using a function handle, only the nested function executes; the outer function, getHandle
, does not. It might seem at first that the variable VExt
, otherwise given a value by getHandle
, has no value assigned to it in the case. What in fact happens though is that MATLAB stores variables such as VExt
inside the function handle itself when it is being constructed. These variables are available for as long as the handle exists.
The VExt
variable in this example is considered to be externally scoped with respect to the nested function. Externally scoped variables that are used in nested functions for which a function handle exists are stored within the function handle. So, function handles not only contain information about accessing a function. For nested functions, a function handle also stores the values of any externally scoped variables required to execute the function.
Example Using Externally Scoped Variables
The sCountFun
and nCountFun
functions shown below return function handles for subfunction subCount
and nested function nestCount
, respectively. These two inner functions store a persistent value in memory (the value is retained in memory between function calls), and then increment this value on every subsequent call. subCount
makes its count
value persistent with an explicit persistent
declaration. In nestCount
, the count variable is externally scoped and thus is maintained in the function handle:
When sCountFun
executes, it passes the initial value for count
to the subCount
subfunction. Keep in mind that the count
variable in sCountFun
is not the same as the count variable in subCount
; they are entirely independent of each other. Whenever subCount
is called via its function handle, the value for count
comes from its persistent place in memory.
In nestCount
, the count
variable again gets its value from the primary function when called from within the M-file. However, in this case the count
variable in the primary and nested functions are one and the same. When nestCount
is called by means of its function handle, the value for count
is assigned from its storage within the function handle.
Running the Example. The subCount
and nestCount
functions increment a value in memory by another value that you pass as an input argument. Both of these functions give the same results.
Get the function handle to nestCount
, and initialize the count
value to a four-element vector:
Increment the persistent vector by 25, and then by 42:
Now do the same using sCountFun
and subCount
, and verify that the results are the same.
Note
If you construct a new function handle to subCount or nestCount , the former value for count is no longer retained in memory. It is replaced by the new value.
|
Separate Instances of Externally Scoped Variables
The code shown below constructs two separate function handles to the same nested function, nestCount
, that was used in the last example. It assigns the handles to fields counter1
and counter2
of structure s
. These handles reference different instances of the nestCount
function. Each handle also maintains its own separate value for the externally scoped count
variable.
Call nCountFun
twice to get two separate function handles to nestCount
. Initialize the two instances of count
to two different vectors:
s.counter1 = nCountFun([100 200 300 400]); count = 100 200 300 400 s.counter2 = nCountFun([-100 -200 -300 -400]); count = -100 -200 -300 -400
Now call nestCount
by means of each function handle to demonstrate that MATLAB increments the two count
variables individually.
Now increment the second counter:
Go back to the first counter and you can see that it keeps its own value for count
:
Variable Scope in Nested Functions | Examples of Nested Functions |
© 1994-2005 The MathWorks, Inc.