eval inside arrayfun gives strange error

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.

 采纳的回答

If you put the function
function y = f(x)
y = eval(sprintf('vec_%d',x));
in a separate file and run the debugger, you'll find that vec_1, etc., are not in the scope of f(x). The same thing is probably true of the anonymous function.
EDIT: This works:
arrayfun(@(x) evalin('base',sprintf('vec_%d',x)),1:4)

5 个评论

Thank you for the explanation and solution for the problem.
Look for the dramatic number of questions here and in CSSM concerning faq4.6 and think twice, if this is really a "solution".
Jan I know that your way is the best one for those kinds of problems, I was just trying to understand why such error occurred.
I selected Andrew answer because he explained what the problem was, provided a workaround and posted first.
I will also vote on your answer, thank you all.
I agree that your approach is better, Jan, but Paulo's question was an interesting puzzle. I also voted for your answer.
I don't think this really addresses the crux of the puzzle: see my answer below.

请先登录,再进行评论。

更多回答(2 个)

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 个评论

I admit, that my answer is not a "solution" also, but more a recommendation not to ask the question at all.

请先登录,再进行评论。

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 个评论

Hi David, thank you for adding more info, I hope this "puzzle" and the answers can help new users.
(1 Vote)
Thanks, David. Bad programming is very educational!

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Word games 的更多信息

产品

Community Treasure Hunt

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

Start Hunting!

Translated by