evalin('base', 'save('var1', 'var2')')

24 views (last 30 days)
Scragmore
Scragmore on 28 Dec 2011
evalin('base', 'save('var1', 'var2')')
I am trying to run a simple function to save specific variables from the base.workspace to a specific location. The variable to be saved and the file name are stored in arrays within the function. As I am learning you can't save base.workspace from the function and you can't send function variables to the base.workspace with 'evalin'.
What is the best way to save base.workspace.array's from a function when the save variables are stored within the function. Do I need to create temp variable on the base.workspace, (I found 'assignin' or 'putvar') then remove. This needs to executed in a loop as my function cycles through the variables saving the relevant files, names to specific locations.
Full Code; NB fOut only used to check function variables are correct.
function fOut = saveData(filterIn)
%to save arrays in work space to C:\Users\Remote\Documents\MATLAB\DATA Files
cd('C:\Users\Remote\Documents\MATLAB\DATA Files');
cd1 = cd;
wSpace = evalin('base', 'whos');
arNames = cell(length(wSpace),1);
arNames = arrayfun(@(x)x.name(1,:), wSpace, 'uniformoutput', false);
if nargin >0
tempIdx = strfind(arNames, filterIn);
index = find(not(cellfun('isempty', tempIdx)));
else
index = find(not(cellfun('isempty', arNames)));
end
for iii = 1:length(index)
iiiTicker(iii,1) = arNames(index(iii,1),:);
iiiTickerChar{iii,1} = char(arNames(index(iii,1),:));
evalin('base', 'save(char(arNames(index(iii,1),:)), char(arNames(index(iii,1),:)))');
end
cd('C:\Users\Remote\Documents\MATLAB');
fOut.cd1 = cd1;
fOut.index = index;
fOut.filterIn = filterIn;
fOut.wSpace = wSpace;
fOut.arNames = arNames;
fOut.tempIdx = tempIdx;
fOut.index = index;
fOut.iii = iiiTicker;
fOut.iiiTickerChar = iiiTickerChar;

Accepted Answer

Jan
Jan on 28 Dec 2011
The command looks nicer when written as:
evalin('base', 'save(arNames{index(iii,1),:}, arNames{index(iii,1),:})')
This will work if arName and iii is defined in the base-workspace as well as the variable with the name called arNames{index(iii,1),:}. But I assume, these variables are defined in the local workspace. Therefore I stringly recommend not to use evalin for such spoofing tricks.
[EDITED]: To create the command string, when arNames, index and iii are defined locally:
name = arNames{index(iii)};
evalin('base', sprintf('save(''%s'', ''%s'')', name, name));
As usual for eval and its evil brothers, enclose this command in a try, catch block and verify that name is a valid symbol, e.g. by:
if strcmp(genvarname(name), name) == 0
error('author:toolbox:badSymbol', ...
'Bad symbol: [%s]', name);
end
This will reduce the risk of a name like "system('format D:')". I do not think, that you use such names. But bugs happen. And by definition bugs are unexpected and have unexpected results. Then it is surely a wise idea to let them not use EVAL/EVALIN as a gun to shoot up your computer. However, avoid EVAL/EVALIN would even be smarter and it is always possible.
  6 Comments
Scragmore
Scragmore on 28 Dec 2011
Jan
Thanks I got it to work.
FYI. evalin('base', sprintf('save(''%s'',''%s'')', nameTemp, nameTemp));
Save needs input as strings.
Before I accept your ans. Is there a better command or function to do this without using the evil twins.
Your description of the evil twins reminds me of old unix.chatroom days when someone would be convinced to run "mv -f \ \dev\null" on their new UNIX box. Ahh they were the days.
Jan
Jan on 28 Dec 2011
There is no better command, but a better design. If you want to save all variables in the base-workspace from a function, you need EVALIN. This has the disadvantage, that you cannot control, which variables are saved.
I'd prefer to store all variables belonging to a certain program in a struct. This struct can be used as input for the function for saving such that a simple SAVE command is working.

Sign in to comment.

More Answers (1)

Fangjun Jiang
Fangjun Jiang on 28 Dec 2011
You need to pay attention to the syntax for using single quote inside the single quote. You could do.
evalin('base', 'save(''MyMatFile'', ''var1'')')
Note the first input argument for save() is the file name, not a variable name.
  6 Comments
Scragmore
Scragmore on 28 Dec 2011
evalin('base', 'save(char(arNames(index(iii,1),:)), char(arNames(index(iii,1),:)))');
runs the 'save' in the base.workspace. The variables |arNames| and |index| exist in the local.function.workspace and are not transfered in evalin.
my function
1) finds arrays in base.workspace that meet search string
2) saves only those arrays using array names as save criteria.
I need save or something similar to be able to save from base.workspace whilst using local.function.variables.
Fangjun Jiang
Fangjun Jiang on 28 Dec 2011
There might be different ways to do it. But I am thinking since the variables are in base workspace, you might just run evalin('base','save(...)') and save it to a temporary file name. Then you can use movefile() to rename the file name according to the string name inside your function.

Sign in to comment.

Categories

Find more on Performance and Memory in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!