How to avoid using eval in this case?

조회 수: 4 (최근 30일)
xiaojuezi
xiaojuezi 2021년 12월 8일
댓글: Matt J 2021년 12월 8일
Hi, I read in multiple threads that the usage of the function eval should be avoided as much as possible. But in the following case I couldn't find a neater way to do so. I have a uicontrol function, and I have several buttons that will set different variables in a similar way. The code is somewhat like below:
w = -1;
h = -1;
editW = uicontrol('Style','edit');
buttonW = uicontrol('Style','pushbutton');
editH = uicontrol('Style','edit');
buttonH = uicontrol('Style','pushbutton');
In total I have more than 5 pushbuttons, each set a specific variable to what is written in the associated edit field. One way to write the callback functions is:
buttonW.Callback = @setW;
buttonH.Callback = @setH;
function setW(hObject,eventData)
w = str2double(editW.String);
end
function setH(hObject,eventData)
h = str2double(editH.String);
end
In this way, I will have to write more than 5 callback functions, which they are simply doing very similar things, making the code look very redundant. So I was thinking using the eval function:
buttonW.Callback = {@setVariable,'w'};
buttonH.Callback = {@setVariable,'h'};
function setVariable(hObject,eventData,input)
% Grab the associated edit field
edit = eval(['edit',upper(input)]);
x = str2double(edit.String);
eval([input '= x']);
end
In this way, I only need to define the function once. Is there other way to somewhat achieve the same effect without using the eval function?
Thank you very much!
  댓글 수: 2
Walter Roberson
Walter Roberson 2021년 12월 8일
function setW(hObject,eventData)
w = str2double(editW.String);
end
I am not clear as to what the purpose is of setting a local variable that is going to be immediately thrown away.
function SetVar(hObject, eventData)
value = str2double(hObject.String);
end
xiaojuezi
xiaojuezi 2021년 12월 8일
Hi, the button is a "OK" button, when a user enters something in the edit field, the variable is only set when they press the button. The variables "w","h"......are also used in global scope. So if there are 6 variables, then there are 6 edit fields and 6 OK buttons, and each button should only control an associated edit field and variable.

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2021년 12월 8일
편집: Matt J 2021년 12월 8일
Store the numeric result to the UserData property of the button, instead of to individual variables.
edit(1) = uicontrol('Style','edit');
button(1) = uicontrol('Style','pushbutton');
edit(2)= uicontrol('Style','edit');
button(2) = uicontrol('Style','pushbutton');
input.edits=edit;
input.buttons=button;
[button.Callback]=deal({@setVariable,input})
function setVariable(hObject,eventData,input)
idx=arrayfun(@(a,b) isequal(a,b), hObject, input.buttons);
hObject.UserData = str2double(input.edits(idx).String);
end
  댓글 수: 3
xiaojuezi
xiaojuezi 2021년 12월 8일
Thank you very much for your answer! I added this button function because users may be changing their input at any time, and the stored values might also be used at different places in the program. So I only want to change the stored values unless users have confirmed what they've entered.
Matt J
Matt J 2021년 12월 8일
You’re welcome. Is the issue solved? If so, please click Accept.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Environment and Settings에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by