I mistakenly said that setEditBoxNumber is a local function. It is a nested function, not a local function.
Why doesn't assignin work in this context?
12 views (last 30 days)
Show older comments
I have a matlab function which creates a variable named 'duration'.
function doStuff()
duration = 5;
Inside the function I create a uicontrol edit box to allow changing the duration value.
uicontrol(panel, 'Style', 'edit', 'Callback', {@setEditBoxNumber, 'duration', 0, 15});
The callback is a local function.
function setEditBoxNumber(obj, ~, ivar, min, max)
value = str2double(get(obj, 'String'));
if isnan(value)
if ~isempty(ivar)
value = evalin('base', ivar);
end
else
value = clip(value, min, max);
end
set(obj, 'String', num2str(value));
if ~isempty(ivar)
assignin('base', ivar, value);
end
value = evalin('base', 'duration');
value = duration;
end
The last two lines are used for debugging purposes. If duration is set to 4 and I type '2' into the text box the string is properly converted to the number 2. The value returned by the bottom evalin call is 2, but the value of duration is still 4.
This is very confusing. If I type letters in the text box the str2double call returns NaN and the upper evalin call properly retrieves the value for duration. I tried using the caller workspace but there was no change in behavior.
Answers (1)
Walter Roberson
on 12 Aug 2015
When you use
value = evalin('base', 'duration');
value = duration;
the first line does not change duration in the current workspace, only in the base workspace. The line after that uses the duration of the current workspace, where it has not been changed. Remove the semicolon from the end of the
value = evalin('base', 'duration');
line to see the value as fetched from the base workspace.
5 Comments
Walter Roberson
on 16 Aug 2015
Edited: Walter Roberson
on 16 Aug 2015
Callbacks are evaluated as if called from the base workspace. If the callback is defined as a nested routine then it can read and write variables in the nesting routine that are assigned values before the nested routine is defined.
function outer
a = 123;
function inner(src, event)
a = 456; %this changes outer's "a"
b = 789; %this changes a local variable "b"
end
b = -11111; %although this belongs to outer, it was not defined before inner() is defined so inner() does not have access to it
set(gcf, 'WindowButtonFcn', @inner)
end
Then the callback of inner() will change outer()'s value of "a", but outer() has already returned so outer() does not get to see the change. If you were to re-execute outer() then because it has the assignment to "a" it would change "a" back to 123. For this reason, functions that nest other functions often end up being "shells" that exist mostly to set something up, with all the real work being done by nested routines whose function handles get stored somewhere.
See Also
Categories
Find more on Data Type Conversion in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!