{"id":21,"date":"2006-02-15T12:16:54","date_gmt":"2006-02-15T17:16:54","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=21"},"modified":"2016-07-28T14:11:15","modified_gmt":"2016-07-28T19:11:15","slug":"nested-function-interaction-with-global-variables","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2006\/02\/15\/nested-function-interaction-with-global-variables\/","title":{"rendered":"Nested Function Interaction with Global Variables"},"content":{"rendered":"<p>\r\nRecently 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.\r\n<\/p>\r\n<p>\r\n\r\nThe 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?\r\n<\/p>\r\n<p>\r\nThe users each wrote GUIs using code with this sort of code structure.\r\n<\/p>\r\n\r\n<pre class=\"code\">\r\nfunction myGUI\r\n \r\nglobal hLines hColor\r\nhfig = figure('name','Changing line colors');\r\nhax = axes('parent',hfig);\r\ninit();\r\n \r\n    function init(varargin)\r\n        hLines = plot(hax,magic(3));\r\n        hColor = uicontrol('style','pushbutton',...\r\n            'string', 'Change line colors', ...\r\n            'units','normalized',...\r\n            'position',[0.01 0.01 0.25 0.05],...\r\n            'callback',@changeColor);\r\n    end\r\n \r\n    function changeColor(varargin)\r\n        colors = {rand(1,3); rand(1,3); rand(1,3)};\r\n        set(hLines, {'Color'}, colors);\r\n    end\r\nend\r\n<\/pre>\r\n<p>\r\nNotice that some of the handles are declared to be global.  Both the <kbd>init<\/kbd> and <kbd>myStop<\/kbd> functions need access to this information, but the main function myGUI doesn't know about them.   However, declaring them <kbd>global<\/kbd> (<kbd>persistent<\/kbd> 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 <kbd>line<\/kbd> and <kbd>uicontrol<\/kbd> handles in the second figure, causing incorrect interactions.\r\n<\/p>\r\nHow can you stop that from happening?  Two ways:\r\n<ol>\r\n<li>\r\nInstead of declaring the shared variables global, simply initialize them.  Replace:\r\n<pre class=\"code\">\r\nglobal hLines hColor\r\n<\/pre>\r\nwith \r\n<pre class=\"code\">\r\nhLines = []; hColor = [];\r\n<\/pre>\r\n<\/li>\r\n<li>\r\nHere's a solution that is perhaps even more elegant.  Since <kbd>init<\/kbd> only gets called once, don't make it a nested function and instead include the code directly in <kbd>myGUI<\/kbd>.  Since that code runs when <kbd>myGUI<\/kbd> is created, the variables in question are automatically initialized to their correct values and are now visible to the <kbd>changeColor<\/kbd> nested function.  The code is now slightly shorter, possibly even more readable, and doesn't have unpleasant side effects.\r\n<\/li>\r\n<\/ol>\r\n\r\n<pre class=\"code\">\r\nfunction myGUIclean\r\n \r\n% initialize GUI\r\nhfig = figure('name','Changing line colors');\r\nhax = axes('parent',hfig);\r\nhLines = plot(hax,magic(3));\r\nhColor = uicontrol('style','pushbutton','units','normalized',...\r\n    'position',[0.01 0.01 0.25 0.05],'string','Change line colors',...\r\n    'callback',@changeColor);\r\n \r\n% callback for pushbutton\r\n    function changeColor(varargin)\r\n        colors = {rand(1,3); rand(1,3); rand(1,3)};\r\n        set(hLines, {'Color'}, colors);\r\n    end\r\nend\r\n<\/pre>\r\n\r\n<p>\r\nFor a more complex GUI example, see <a href=\"https:\/\/www.mathworks.com\/company\/newsletters\/articles\/programming-patterns-nested-functions-in-matlab.html\">The MathWorks News & Notes - January 2006 article<\/a> and find the code on the MATLAB File Exchange.\r\n<\/p>","protected":false},"excerpt":{"rendered":"<p>\r\nRecently 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... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2006\/02\/15\/nested-function-interaction-with-global-variables\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,6],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/21"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=21"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/21\/revisions"}],"predecessor-version":[{"id":1790,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/21\/revisions\/1790"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=21"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=21"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=21"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}