필터 지우기
필터 지우기

Executing eval in function handle ?

조회 수: 3 (최근 30일)
holistic
holistic 2018년 3월 18일
댓글: Jan 2018년 3월 19일
I have the following code which does not work and I don't understand why:
foo='name'
name='C23';
handle=@(var) eval(var)
handle(foo)
I get the following error:
Error using eval
Undefined function or variable 'name'.
Error in @(var)eval(var)
Here,
handle(foo)
should return
'C23'
Can someone tell me what I did wrong and how to make this work?
Thanks in advance
  댓글 수: 3
holistic
holistic 2018년 3월 19일
편집: holistic 2018년 3월 19일
Thanks all for the answers so far,
I will describe a simplified example of what I wanted to achieve with this code. A string should be build that contains the name and surname, but the order should be defined by the user.
nameOrder={'surname','name'}; %Specified by user
handle=@(var) strcat(eval(var{1}),'_',eval(var{2})); %function handle that builds string
surname='test'; %read from data automatically
name='guy'; %read from data automatically
handle(nameOrder) %output to user should be test_guy
In this case nameOrder is set by the user which chose surname and then name. Later, there is a routine that reads in name and surname from some data and should output a string that is the name and surname or surname and name, i.e. the order specified by the user.
I could not think of any other way to do this, so any help appreciated!
Stephen23
Stephen23 2018년 3월 19일
"I could not think of any other way to do this"
Using eval is rarely the solution that beginners think it is: it will just make your code slow, complex, and (as you are finding out now) much buggier and harder to debug. Read this to know more:

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

채택된 답변

Stephen23
Stephen23 2018년 3월 19일
편집: Stephen23 2018년 3월 19일
This is a classic example of how the decision to use eval to access variables just makes code more complex and introduces more problems than it solves. The name MATLAB comes from "MATrix LABoratory": when you put your data into matrices/arrays then this problem is easy to solve. Thus the first step is to simply put the input data into one cell array (which they should be in anyway, rather then in separate variables):
>> nameOrder = {'sur','given'};
>> sname = 'Smith';
>> gname = 'Jane';
>> tmp = {gname,sname}; % first step: put into one array!
>> [~,idx] = ismember(nameOrder,{'given','sur'});
>> sprintf('%s_%s',tmp{idx})
ans = Smith_Jane
Simple, reasonably efficient, and it avoids all of the pointless problems of eval. I changed the variable names and char vectors to make it clear that the nameOrder contents are not the same as the variable names. You could simplify it even more by storing the names in a standard format, e.g. perhaps a structure:
S.surname = 'Smith';
S.givenname = 'Jane';
tmp = {S.givenname,S.surname};
Note that using a cell array has the advantage that you could write code which takes into account cultures which have multiple or only one name, all of which could be handled trivially with indexing (and not an eval in sight!).
Summary: keep data together as much as possible, rather than splitting it apart. Keeping data together makes it easier to work with.
  댓글 수: 2
holistic
holistic 2018년 3월 19일
Ah I see, that's a much better solution :). Thank you!
Jan
Jan 2018년 3월 19일
Very good. +1

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

추가 답변 (1개)

Greg
Greg 2018년 3월 19일
Most importantly! respond to Rik's comment above. The use of eval is very nearly always a horrible idea.
However, to your question: it does not work because the scope of name is where the anonymous function is defined. When executing the anonymous function, name is out of scope in that workspace.
  댓글 수: 1
Greg
Greg 2018년 3월 19일
I hesitate to mention it could work if you used evalin('caller',...); but again, bad idea!

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

카테고리

Help CenterFile Exchange에서 Interactive Control and Callbacks에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by