octave-maintainers
[Top][All Lists]
Advanced

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

Re: locally changing global variables


From: Jaroslav Hajek
Subject: Re: locally changing global variables
Date: Tue, 18 May 2010 07:53:12 +0200

On Tue, May 18, 2010 at 7:43 AM, John W. Eaton <address@hidden> wrote:
> 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?
>

Currently, I think not. It would be possible if we had a working
onCleanup implementation. Despite we have unwind_protect, which is, in
most practical ways, more versatile, onCleanup being an object allows
for doing magic, such as injecting a cleanup action to caller scope
(which could be the solution here). I'll start a separate thread about
this.

-- 
RNDr. Jaroslav Hajek, PhD
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz



reply via email to

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