(octave.info)Nested Functions


Next: Overloading and Autoloading Prev: Private Functions Up: Function Files
Enter node , (file) or (file)node

11.9.4 Nested Functions
-----------------------

Nested functions are similar to subfunctions in that only the main
function is visible outside the file.  However, they also allow for
child functions to access the local variables in their parent function.
This shared access mimics using a global variable to share information —
but a global variable which is not visible to the rest of Octave.  As a
programming strategy, sharing data this way can create code which is
difficult to maintain.  It is recommended to use subfunctions in place
of nested functions when possible.

   As a simple example, consider a parent function ‘foo’, that calls a
nested child function ‘bar’, with a shared variable X.

     function y = foo ()
       x = 10;
       bar ();
       y = x;

       function bar ()
         x = 20;
       endfunction
     endfunction

     foo ()
      ⇒ 20

Notice that there is no special syntax for sharing X.  This can lead to
problems with accidental variable sharing between a parent function and
its child.  While normally variables are inherited, child function
parameters and return values are local to the child function.

   Now consider the function ‘foobar’ that uses variables X and Y.
‘foobar’ calls a nested function ‘foo’ which takes X as a parameter and
returns Y.  ‘foo’ then calls ‘bat’ which does some computation.

     function z = foobar ()
       x = 0;
       y = 0;
       z = foo (5);
       z += x + y;

       function y = foo (x)
         y = x + bat ();

         function z = bat ()
           z = x;
         endfunction
       endfunction
     endfunction

     foobar ()
         ⇒ 10

It is important to note that the X and Y in ‘foobar’ remain zero, as in
‘foo’ they are a return value and parameter respectively.  The X in
‘bat’ refers to the X in ‘foo’.

   Variable inheritance leads to a problem for ‘eval’ and scripts.  If a
new variable is created in a parent function, it is not clear what
should happen in nested child functions.  For example, consider a parent
function ‘foo’ with a nested child function ‘bar’:

     function y = foo (to_eval)
       bar ();
       eval (to_eval);

       function bar ()
         eval ("x = 100;");
         eval ("y = x;");
       endfunction
     endfunction

     foo ("x = 5;")
         ⇒ error: can not add variable "x" to a static workspace

     foo ("y = 10;")
         ⇒ 10

     foo ("")
         ⇒ 100

The parent function ‘foo’ is unable to create a new variable X, but the
child function ‘bar’ was successful.  Furthermore, even in an ‘eval’
statement Y in ‘bar’ is the same Y as in its parent function ‘foo’.  The
use of ‘eval’ in conjunction with nested functions is best avoided.

   As with subfunctions, only the first nested function in a file may be
called from the outside.  Inside a function the rules are more
complicated.  In general a nested function may call:

  0. Globally visible functions

  1. Any function that the nested function’s parent can call

  2. Sibling functions (functions that have the same parents)

  3. Direct children

   As a complex example consider a parent function ‘ex_top’ with two
child functions, ‘ex_a’ and ‘ex_b’.  In addition, ‘ex_a’ has two more
child functions, ‘ex_aa’ and ‘ex_ab’.  For example:

     function ex_top ()
       ## Can call: ex_top, ex_a, and ex_b
       ## Can NOT call: ex_aa and ex_ab

       function ex_a ()
         ## Can call everything

         function ex_aa ()
           ## Can call everything
         endfunction

         function ex_ab ()
           ## Can call everything
         endfunction
       endfunction

       function ex_b ()
         ## Can call: ex_top, ex_a, and ex_b
         ## Can NOT call: ex_aa and ex_ab
       endfunction
     endfunction


automatically generated by info2www version 1.2.2.9