Loren on the Art of MATLAB

Evading eval 5

Posted by Loren Shure,

If you are a regular reader of the MATLAB Usenet newsgroup, comp.soft-sys.matlab, found on the MathWorks User Community page, you are probably familiar with repeated advice to not use the MATLAB function eval . Today I plan to tell you more about why this is generally good advice.

Code Clarity / Readability

Statements containing a call to eval have a way of obscuring the underlying intent of the code though this is rarely a goal of the author. What do I mean by this? Well, in under 3 seconds, can you discern what the following code means?

a = who ;
a = a(~cellfun('isempty',regexp(a,'2$'))) ;
str = sprintf('%s,',a{:}) ;
str = sprintf('B = cat(1,%s) ;',str(1:end-1)) ;
eval(str) ; 

Unless you are one of the proponents of this code pattern (see this newsgroup post, for example), you likely couldn't tell that the code is saying

Concatenate all variables that have '_2' in their name, i.e. a_2, b_2, c_2

Efficiency

When a function M-file is run in MATLAB for the first time in a session, MATLAB reads in the file, translates it into an internal representation, analyzes the contents, and executes the code. The next time you use this function in the same MATLAB session, assuming the file hasn't changed, MATLAB doesn't need to reread and translate the file.

However, if the M-file contains any calls to the function eval, at least those lines of code will need to be reinterpreted each time the function is run. Why? Because there is no guarantee, and it is generally not true, that the expression that was executed in the first instance is the same as subsequent ones. The expression may require different MATLAB functions or variables. In any case, to be sure MATLAB gets the right answer, at least the lines of code containing eval statements need to be re-analyzed with each invocation.

Analyzability

In an M-file, if the functions being called are coded into strings so they can be placed into eval statements, it is very difficult to build up a complete understanding of the functions and files that your M-file depends upon, especially in a static way. It might be possible, though probably difficult and perhaps error-prone, to scan through an M-file to see where strings are used in eval statements and to try to pull out the possible function and file names from these.

Techniques to evade eval

5 CommentsOldest to Newest

Thanks for a great article Loren,
I came across it cause I have been experiencing problems with how terrebly slow the eval function is.
I have a large code, and thought I could speed it up by avoiding some calculations and using the eval, but the running time exploded!
Lesson:avoid eval by all means :)

Well, big thank you Loren!

I was a bit desperate because I thought I was forced to use the eval function in my code. And of course the calculation time just skyrocketed…

But now, I know how not to use that lazy function.

Thanks again !

Hi Loren & list,

I have used EVAL to perform the following loop statement to create n variables named s1, s2, …, etc. containing a string

for i = 1:10
eval(['s' num2str(i) '=' 'file'])
end

but what I really want to do is name the strings ‘file1′,
‘file2′, …, etc. which does not seem to work with EVAL


for i = 1:10
eval(['s' num2str(i) '=' 'file' num2str(i)])
end

Do you have any suggestions for avoiding EVAL ?

Best,
Martin

Martin,

Creating variables named s1, s2, s3, etc. is generally a bad idea for several reasons, some of which Loren called out in her blog post and others of which are discussed in the Programming section of the comp.soft-sys.matlab FAQ:

http://matlab.wikia.com/wiki/FAQ

I would use a cell array for this task.

s = cell(1, 10);
for k = 1:10
    s{k} = sprintf('file%d', k);
% or
%   s{k} = ['file' num2str(k)];
end

To extract one of the strings (for example, ‘file5′) from the cell array use curly brace indexing:

myfilename = s{5}

or you could iterate over the cells in the cell array using a FOR loop or the CELLFUN function.

for k = 1:numel(s)
    fprintf('String number %d is %s.\n', k, s{k});
end

Hi Steve,

I of course realized immediately that using cell arrays is much more flexible programming. Thanks for your comment!

Martin

These postings are the author's and don't necessarily represent the opinions of MathWorks.