preserving variable class when extracting fields from a struct

1 view (last 30 days)
I have a program that requires passing a large number of variables to a function. Rather than have a long list of global variables, I'd rather pack them into a struct, declare the struct as global, then unpack the struct in the function workspace. Obvously, a requirement is that the class of the original variable is preserved after unpacking. I had hoped that the new matlab command extractfield would do this, but it doesn't, since, it appears, any nonnumeric variable is output as a cell array. Is there a clean way of doing this? Here's an example
myCell = {'word'};
myString = 'word';
S.cellVar = myCell;
S.stringVar = myString;
FieldNames = fieldnames(S);
for ii=1:numel(FieldNames);
eval([ FieldNames{ii} '=extractfield(S,FieldNames{ii});']);
end;
class(cellVar)
class(stringVar)
I would like a clean way of ensuring that character strings like stringVar are output as strings not cells. Or perhaps somebody has a better way altogether of passing multiple variables to subroutines.
Thanks for any recommendations.
  1 Comment
Stephen23
Stephen23 on 4 Nov 2015
Edited: Stephen23 on 5 Nov 2015
"unpacking" using eval is the total opposite of "a clean way" to obtain particular values. Read my answer thoroughly to know why.

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 4 Nov 2015
Edited: Stephen23 on 12 Sep 2023
All of that "packing" and "unpacking" is a total waste of time, space and code. Just define those values to be part of the structure right from their definition, pass the structure as an input argument to that function, and then use the fields of the structure directly within that function.
And of course avoid using global, or creating dynamically named variables:

More Answers (3)

Jan
Jan on 4 Nov 2015
Packing variables into a global struct and unpacking it afterwards is too indirect to deliver variables to functions. Why not providing the struct directly as input and using the struct without unpacking?
Matlab accelerates code substantially with the JIT. Variables, which are created dynamically using eval prevents this acceleration, such that the performance of the code can be 100 times worse.
If you are really convinced, that the fields of the struct should be "unpacked", do this manually. This does not only allow the JIT to be efficient, but saves a lot of time for debugging:
try
Data = S.Data;
Value = S.Value;
Unit = S.Unit;
...
catch ME
error(...)
end
This might look less clear at first, but imagine that this piece of code is a part of a 100'000 lines of code program. Then a clear error message is much mor important than a piece of code, which hides what's going on in cryptic eval expressions and dynamically created variables.

Walter Roberson
Walter Roberson on 4 Nov 2015
Using eval() makes for broken code.

Thorsten
Thorsten on 4 Nov 2015
Edited: Thorsten on 4 Nov 2015
fn = fieldnames(S);
for i = 1:numel(fn)
eval([fn{i} '= getfield(S, ''' fn{i} ''');'])
end
But instead I would recommend to rewrite your code inside the function from
myString = 'bar';
to
S.myString = 'bar';

Categories

Find more on Variables in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!