eval inside arrayfun gives strange error
Afficher commentaires plus anciens
Can someone explain why this doesn't work?
vec_1=[1 2 3 4];
vec_2=[5 6 7 8];
vec_3=[9 10 11 12];
vec_4=[13 14 15 16];
arrayfun(@(x)eval(sprintf('vec_%d',x)),1:4)
??? Error using ==> eval
Undefined function or variable
'vec_1'.
Error in ==>
@(x)eval(sprintf('vec_%d',x))
I'm just curious about this strange behavior, it says that vec_1 isn't defined but it is!
Thank you in advance
PS: This is related to http://www.mathworks.com/matlabcentral/newsreader/view_thread/303123 but I didn't get a reply, just a comment from someone acting like a douchebag.
Réponse acceptée
Plus de réponses (2)
Jan
le 20 Fév 2011
Instead of using complicated methods to access complicated names of variables, which contain a textual index, simply use an index as index (sic!):
E.g.: vec{1}, vec{2}, ... or create a matrix and use the rows:
mat = [1 2 3 4; ...
5 6 7 8; ...
9 10 11 12; ...
13 14 15 16];
% Now your "vec_1" is equivalent to mat(1, :)
Using an index is obvioulsy less confusing and prone to errors than a ARRAYFUN(EVALIN) gimmick. And it is much faster also.
2 commentaires
Paulo Silva
le 20 Fév 2011
Jan
le 20 Fév 2011
I admit, that my answer is not a "solution" also, but more a recommendation not to ask the question at all.
David Young
le 20 Fév 2011
First, I have to add myself to the list of people for whom it is painful to see someone using sequential variable names constructed at run-time.
Having said that, there is a puzzle here, and Andrew's answer doesn't address all the details, though it is fundamentally correct.
First note this:
vec_1 = [1 2 3 4];
f = @(x) vec_1 + x;
f(100)
which prints
ans =
101 102 103 104
So the value of vec_1 is available to the anonymous function. (And thus this is not like the situation Andrew describes for a function in a separate file, because such a function never knows the value of vec_1, unless it's global or passed as an argument.)
On the other hand,
g = @(x) eval('vec_1 + x');
g(100)
produces
??? Error using ==> eval
Undefined function or variable 'vec_1'.
But we expect that in general executing eval({code}) should be the same as executing {code}, whether or not it's inside a function. So something is going on. (And, by the way, arrayfun is a red herring.)
The answer is in the documentation, at http://www.mathworks.com/help/techdoc/matlab_prog/f4-70115.html, which contains this:
- "Upon construction [of an anonymous function], MATLAB captures the current value for each variable specified in the body of that function. The function will continue to associate this value with the variable even if the value should change in the workspace or go out of scope."
So the anonymous function never incorporates vec_1 as a variable: the value of vec_1 gets built into the function f when the function is constructed.
On the other hand, when the function g above is constructed, all the compiler sees is the constant string 'vec_1 + x'. It can't be expected to look inside the string for a variable name (indeed we wouldn't want it to). Thus eval gets passed the string as it stands, without a value substituted for vec_1 - and, as Andrew says, vec_1 isn't actually in the scope of the function.
2 commentaires
Paulo Silva
le 20 Fév 2011
Andrew Newell
le 21 Fév 2011
Thanks, David. Bad programming is very educational!
Catégories
En savoir plus sur Word games dans Centre d'aide et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!