Loren on the Art of MATLAB

January 4th, 2006

More on eval

I recently wrote an article on Evading eval. A couple of users asked me how to avoid using eval in the case post under Code Clarity / Readability. The answer is you can't, unless you rethink the code altogether.

Where did the variables come from and who established the naming convention? If it was you the programmer, then you have some great options for avoiding the hard-to-understand code.

First option: structures

You can create names that you want as fields of a structure and use fieldnames and dynamic field references.

Second option: cell arrays

You can use cell arrays to hold the variables and use cell indexing to get the contents for any particular array. See the FAQ for more information which I will quote here:

Now, if you still really want to create variables with dynamically generated names, you need to use eval. With eval, you use MATLAB commands to generate the string that will perform the operation you intend. For example, eval('A=10') has the same effect as A=10, and eval(['A' 'B' '=10']) has the same effect as AB=10, only the eval method executes much more slowly. So in a loop, you could use:

for i=1:10
  eval(sprintf('A%d = [1:i]', i));
end

Notice how much more obfuscated this is. Repeat: don't do this unless you have a very good reason (such as someone gives you a MAT file with 2000 variables named A1428, for example).

The only thing I would add to this is that you could indeed load the variables in the MAT-file into a structure, by writing something like this:

                      MyData=load('data.mat');

The variable MyData is a struct with the variable names in the MAT-file as the field names. So once again, you can use dynamic field references to rescue your code.

2 Responses to “More on eval”

  1. Hiroshi Furutani replied on :

    Hi Loren,
    I understand why creating variable with dynamically-assigned name should be avoided. It will be very complex on Matlab. But I have to admit that variables with specific names are really useful to understand the content later and further data analysis. Just looking at the workspace, one can understand the content.

    Is there any better and practical way to make both sides happy?

  2. Loren replied on :

    Hiroshi-

    I recommend using dynamic field names with structures. Here’s an example:

    label = 'loren'
    d.([label] str2int(4) = data{4};
    %% now there's a struct with field 'loren4'
    

    –Loren

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Loren Shure works on design of the MATLAB language at The MathWorks. She writes here about once a week on MATLAB programming and related topics.

  • Jun: I totally can not believe it, Loren. You are really helpful. Thank you so much, MATLAB master!
  • Loren: Wow folks- Always lots of interest when there’s a quickie to try out! I will only make 2 general...
  • Loren: Jun- ismember is your friend here: >> [aa,ind] = ismember(Array2,Arra y1) aa = 1 1 1 1 1 1 1 ind = 1 2 1 4 4 3...
  • Dan: I like the first way better than the second way. Combining the arrays into one and running any is nice, although...
  • James Myatt: How about I = (a == 0 | b == 0); a(I) = []; b(I) = [];
  • Tunc: Hello Loren, love your blog because of such inspiring and challenging comments to such ’small’...
  • Pekka Kumpulainen: Here is my tradeoff. I usually want to keep the original variables as they are most probably...
  • Iain: Followup: Of course, to allow NaNs (counting them as non-zero): mask = (a~=0) & (b~=0); The mask says “a...
  • Matt Fig: I would usually go with something like this: y = a&b; x = a(y); y = b(y); But I was surprised to find...
  • kk: c=all([a;b]) a(c) a(b)

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