How to load many variables form base environment
조회 수: 6 (최근 30일)
이전 댓글 표시
Dear reader,
Here is a toy example. Inside a user-defined function, I currently use the following syntax:
a = evalin('base', 'a');
b = evalin('base', 'b');
c = evalin('base', 'c');
which allows me to load 3 matlab variables, called a,b,c from base environment into the current function's workspace. In reality I have many more variables, not only 3. Therefore, I am looking for a more elegant way to write this code.
A solution would be to write a new matlab function (I'll call it loadVarsFromBaseEnv.m) which should permit me to call it as follows:
loadVarsFromBaseEnv a b c
However, I have no idea how to write the code of loadVarsFromBaseEnv.m
Any help, suggestion are highly appreciated.
댓글 수: 0
채택된 답변
per isakson
2015년 4월 7일
편집: per isakson
2015년 4월 7일
"goal is not to write nice matlab code, but instead structure it in the most convenient way"   How come you believe there is conflict between "nice" and "convenient"? Whatever these words mean in this context.
Here is an "elegant" code that meets your original requirements. Example of use:
a = 1;
b = magic(3);
c = dir;
JustGetTheWorkDone a b c
prints
Name Size Bytes Class Attributes
a 1x1 8 double
b 3x3 72 double
c 89x1 57407 struct
varargin 1x3 342 cell
where
function JustGetTheWorkDone( varargin )
loadVarsFromBaseEnv( varargin{:} )
whos
end
and
function loadVarsFromBaseEnv( varargin )
try
for jj = 1 : length( varargin )
val = evalin( 'base', varargin{jj} );
assignin( 'caller', varargin{jj}, val )
end
catch
fprintf( 2, 'loadVarsFromBaseEnv: Something went wrong\n' ) %#ok<PRTCAL>
end
end
추가 답변 (1개)
Stephen23
2015년 4월 7일
편집: Stephen23
2015년 4월 7일
"a more elegant way to write this code" would be to pass the variables properly and not make them pop into existence in some workspace like that. The reason that you are finding it difficult is because this is not how passing variables to functions works... that is exactly what function input arguments are for. And indeed, passing arguments is what MATLAB themselves recommend as being best practice:
Note that after the best practice of using the input arguments properly comes using nested functions and then global variables. Have you tried any of these?
The MATLAB Wiki also states that "two related functions, evalin and assignin, can be used to alter variables in different function workspaces. These functions can create bugs which are difficult to reproduce and nearly impossible to eliminate."
For some reason beginners seem to love inventing magical ways of making variables appear and disappear in all sorts of unexpected places, but this is not good programming style and doing this makes tracking the functionality and code debugging extremely difficult. Avoid doing this and learn how to pass variables properly, or use nested functions, etc.. If you want the variables to be more convenient to pass around, put them together in one structure.
The function assignin (just like evalin and eval) is a very powerful tool that short circuit lots of inbuilt code checking and syntax highlighting. It is slower than calling normal code due to JIT having to re-evaluate on every call.
http://de.mathworks.com/matlabcentral/answers/110865-assignin-caller-to-variables-performance-issues
Although many of these pages relate to eval the same comments often apply, so here are some pages explaining why dynamically assigning variable names is a really bad idea in MATLAB:
댓글 수: 5
Image Analyst
2015년 4월 7일
You can do that, no problem. As you know, if you take only the first return argument from a function, that's fine. Even if the function, or a newer version of it, returns other parameters, you don't have to change your code. The early functions that dealt only with a will be fine -- they don't need to be changed to accept b and c, which they would not even use anyway. And the other m-files which needed b and c, and are the reason you added b and c as return arguments, can accept all 3 return arguments and do whatever they want with them. So there is no reason you will need to change tons of old m-files. The only reason you'd have to do that is if you changed the meaning of what was a, b, and c. For example if the single return argument in early versions was now the middle or last argument in the list, like if you unwisely had function [b,a,c] = parameters(). That would be a bad idea.
Stephen23
2015년 4월 8일
편집: Stephen23
2015년 4월 8일
@Stefan: a much tidier solution would be to use a structure. So instead of this:
[a,b,c,...] = parameters()
with some unknown number of arguments, you would always simply call this:
X = parameters();
and then refer to the appropriate field in your code:
X.data % or whatever field
this still gives the advantage of individually named (and identifiable) fields, and lets you pass just one variable around. No assignin required!
It is even possible to store this structure in one Mfile that can be designed to add fields on-the-fly, and return selected fields. Something like this:
function out = parameters(field,val)
persistent store
switch nargin
case 0
out = store;
case 1
if isfield(store,field)
out = store.(field);
else
% error or empty output
end
case 2
store.(field) = val
end
end
Which can then be set easily:
>> parameters('data',1)
>> parameters('total',5)
and accessed in the same way:
>> parameters
ans =
data: 1
total: 5
>> parameters('data')
ans =
1
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!