octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

locally changing global variables


From: John W. Eaton
Subject: locally changing global variables
Date: Tue, 18 May 2010 01:43:24 -0400

On 10-May-2010, Jaroslav Hajek wrote:

| Octave's global pseudo-variables are a useful tool for customizing
| Octave's settings, yet they present problems when a function is
| dependent on a particular state of a certain variable. A typical
| instance in my work is console output magic used for progress tracking
| of a lengthy task that may be delayed or even completely spoiled by
| the pager. A temporary change of a particular variable can be achieved
| by unwind_protect:
| 
| function progress(n)
|   old_pso = page_screen_output (false);
|   unwind_protect
| 
|     for i = 1:n
|       printf ("\r%d", i);
|       pause (0.25);
|     endfor
|     printf ("\rdone.\n");
| 
|   unwind_protect_cleanup
|     page_screen_output (old_pso);
|   end_unwind_protect
| endfunction
| 
| this is, however, somewhat wordy and ugly, requiring the programmer to
| enclose the whole function body in an unwind_protect block, and
| explicitly invent the variable name for storing the old value.
| 
| What I propose is to enable calling the pseudo-variables with a
| "local" option argument, requesting the variable to be restored when
| the current function exits. Thus, the previous function could be
| written like this:
| 
| function progress(n)
|   page_screen_output (false, "local");
| 
|   for i = 1:n
|     printf ("\r%d", i);
|     pause (0.25);
|   endfor
|   printf ("\rdone.\n");
| endfunction
| 
| this is, of course, much more readable.
| 
| An incomplete (no ChangeLogs & no docs) patch is attached. The patch
| implements the cleanup action very efficiently, reusing the existing
| unwind_protect frame inside the calling function. Hence, besides being
| more readable, the second form should also be more efficient. Multiple
| variables may be changed at any point in the function, and they will
| all be restored (in the reverse order) at the very end of the
| function.
| 
| Comments? Suggestions?

Sorry for the late reply on this.  I don't object to this change as it
does make temporary settings somewhat easier.

Do your current changes apply only to internal variables?  How can
something similar be done for variables that are managed entirely by a
user-defined function?  For example, one nice thing about switching
from actual variables for user preferences to functions was that we
made it possible for users to write functions like

  function retval = my_special_value (val)
    persistent curr_val = "default_value";
    if (nargin == 1)
      if (nargout > 0)
        retval = curr_val;
      endif
      curr_val = val;
    elseif (nargin == 0)
      retval = curr_val;
    else
      print_usage ();
    endif
  endfunction

Is it possible to adapt a function like this to accept a second
"local" argument?

jwe


reply via email to

[Prev in Thread] Current Thread [Next in Thread]