Skip to Main Content Skip to Search
File Exchange
MATLAB Newsgroup
Link Exchange
  Blogs  
 Contest 
MathWorks.com

Loren on the Art of MATLAB

February 15th, 2006

Nested Function Interaction with Global Variables

Recently on two different occasions, people have asked me to help debug their nested function code. I was struck by the similarity of their problems and today will show you the problem and some solutions.

The problem, simply stated, is this. The users wrote GUIs using nested functions and brought up a single instance which ran fine. Then they brought up a second instance while the first one was running, and ran the second one. So far, so good. Then each user went to the original GUI window and pushed a button. To the surprise of those watching, the action all happened in the second GUI from that moment forward, regardless of which GUI's button was pressed. What was happening?

The users each wrote GUIs using code with this sort of code structure.

function myGUI
 
global hLines hColor
hfig = figure('name','Changing line colors');
hax = axes('parent',hfig);
init();
 
    function init(varargin)
        hLines = plot(hax,magic(3));
        hColor = uicontrol('style','pushbutton',...
            'string', 'Change line colors', ...
            'units','normalized',...
            'position',[0.01 0.01 0.25 0.05],...
            'callback',@changeColor);
    end
 
    function changeColor(varargin)
        colors = {rand(1,3); rand(1,3); rand(1,3)};
        set(hLines, {'Color'}, colors);
    end
end

Notice that some of the handles are declared to be global. Both the init and myStop functions need access to this information, but the main function myGUI doesn't know about them. However, declaring them global (persistent would have the same effect here since there's only one file) is what's causing the first and second instances to both point to the line and uicontrol handles in the second figure, causing incorrect interactions.

How can you stop that from happening? Two ways:
  1. Instead of declaring the shared variables global, simply initialize them. Replace:
    global hLines hColor
    
    with
    hLines = []; hColor = [];
    
  2. Here's a solution that is perhaps even more elegant. Since init only gets called once, don't make it a nested function and instead include the code directly in myGUI. Since that code runs when myGUI is created, the variables in question are automatically initialized to their correct values and are now visible to the changeColor nested function. The code is now slightly shorter, possibly even more readable, and doesn't have unpleasant side effects.
function myGUIclean
 
% initialize GUI
hfig = figure('name','Changing line colors');
hax = axes('parent',hfig);
hLines = plot(hax,magic(3));
hColor = uicontrol('style','pushbutton','units','normalized',...
    'position',[0.01 0.01 0.25 0.05],'string','Change line colors',...
    'callback',@changeColor);
 
% callback for pushbutton
    function changeColor(varargin)
        colors = {rand(1,3); rand(1,3); rand(1,3)};
        set(hLines, {'Color'}, colors);
    end
end

For a more complex GUI example, see The MathWorks News & Notes - January 2006 article and find the code on the MATLAB File Exchange.

3 Responses to “Nested Function Interaction with Global Variables”

  1. DavidB replied on :

    Hi, I think your example with nested are nice and i cant do the same.
    I am running Matlab6 but no way to share variable efficiently
    -for exemple I run the nested function ‘taxdemo’
    taxDemo(30) %%Matlab example
    ” ??? Undefined function or variable ‘AdjustedIncome’.”

    Furthermore, when I am inside a function into i cannot access global variables defined in the main workspace, with the exception of nested global variables, for exemple somthing like that:
    function param=opt(goal)
    global G
    G=goal;
    …..
    param = lsqnonlin(@circuit,Z0,LB,HB,cond);
    function F = circuit(Z)
    %acces global
    end
    end

  2. Loren replied on :

    Nested functions are a new feature in MATLAB 7 which is why the code didn’t work in MATLAB 6 when you tried it there.

    I recommend you read the documentation on using global variables to understand how to access them. In each workspace that you want to see a particular global variable, you must declare that before making reference to it. This includes functions and the base workspace.

  3. Rehan replied on :

    Hi
    I have built my code in MATLAB 7. I have a problem. I used global variables in the function for example img_global. Now by using imread, I get the input image and using imshow create an instance showing image. Later in the function, I create another using figure(’Name’, ‘Label’) alongwith the msgbox of the result. msgbox and seconf figure is there but first figure disappears. Please help

Leave a Reply


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • Loren: Timothee- Anonymous functions can only be a single (complicated) expression. You might be able to do what you...
  • Timothee: Is there a way to combine multiple commands in anonymous functions? ex1: fun=@(A)([V,D]=eig(A ); A*V-V*D)...
  • Loren: Here’s Cleve’s reply to Etienne: The crucial factor is the number and location of the nonzero...
  • Loren: Tristan- Nested functions can be slower in some cases currently. We know we have some opportunities to...
  • Tristan: Wow! I just tried with a global variable and it’s 5 times slower than with a argument! function...
  • Jon: Loren, I encountered this same problem and I attempted to find the answer by looking at the documentation for...
  • Tristan: “One thing that I have long wondered about is relative speed of nested functions relative to...
  • Etienne Non: Hi! I’m trying to understand why the Matlab function LU.m takes almost 20 times more time to...
  • Loren: Jonathan- The behavior you see is because the variable x has to come into inplaceTest and then a copy is made...
  • Jonathan: I am calling it from another function, but have just noticed a bit more odd behavior. Here is what...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.

Related Topics