Note that there are some explanatory texts on larger screens.

plurals
  1. POCan `eval()` be avoided? (Assign variable name at runtime)
    text
    copied!<p>I have written a script that saves me to manually import in Matlab the data recorded during tests.</p> <p>Each test run saves around 2600 variables in <code>.csv</code> files, each with 2 header lines, two columns of data and <code>;</code> is the separator.</p> <p>The filenames come from an internal C-struct used by the monitoring program and are thus of this kind: <code>foo.bar.another.foo.bar.local_varname#VALUE.csv</code> and I want to use this to re-create the struct in Matlab in order to save only that in a <code>test_name.mat</code> file.</p> <p>Many times the <code>local_varname</code> is more than 63 char long, so I have some substitution rules in order to shorten the names without having Matlab truncating the names (and so trying to avoid naming conflicts).</p> <p>This is the code</p> <pre><code>clear all clc % Main names path_self = pwd; backslash_indices = strfind(path_self,'\'); test_name = path_self(backslash_indices(end)+1:end); % the directory name gives me the test_name % Preallocation filenames = cell(1,2600); addresses = cell(1,2600); i=0; % Full list MyFiles = dir(path_self); % Discard subdirectories and non interesting files for k=1:length(MyFiles) if ~MyFiles(k).isdir, if ~isempty(strfind(MyFiles(k).name,'#VALUE.csv')) i=i+1; % Too many files if i &gt; length(filenames) filenames = [filenames cell(1,100)]; addresses = [addresses cell(1,100)]; end % Naming Substitution Rules %%% INSERT HERE BUNCH OF RULES % Addresses and names filenames{i} = strrep(filename,'#VALUE.csv',''); addresses{i} = fullfile(path_self, MyFiles(k).name); end end end filenames = filenames(1:i); addresses = addresses(1:i); % Check that no conflicts are created if length(filenames) ~= length(unique(filenames)) error('filenames not unique') end % Housekeeping #1 clear MyFiles backslash_indices i k path_self % Import data for j=1:length(filenames) % Read data Data = importdata(addresses{j}, ';', 2); % Assign data eval([filenames{j}, '.time = Data.data(:,1)./1000000;']); % Converted in seconds eval([filenames{j}, '.values = Data.data(:,2);']); % Let's avoid data corruption clear Data end % Housekeeping #2 clear filenames addresses j % Save data struct save(test_name, '-regexp', '^((?!name).)*$') </code></pre> <p><strong>Now my question</strong> While researching information and help to write the above code I often found people frowning upon the use of <code>eval()</code>: why is it so? In the above situation, can I avoid it?</p> <p>Thanks</p> <p><strong>EDIT</strong> As suggested by @wakjah, I tested a <code>containers.Map()</code> approach. Unfortunately is not suited to our needs, since at that point a list of keys is needed and accessing the data is not exactly friendly (remember that I have ~2600 variables, meaning at least the same number of keys)</p> <p>As for what has been asked by @Dennis Jaheruddin, the data struct is usable and does not creates any kind of conflict, even with these long varnames (given that each name* between two consecutive <code>.</code> is less than 63 chars long)</p> <p>*my apologies for not using a better technical term</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload