Copying option structs by value instead of reference

Here is an example using bodeoptions, but this is probably a much more basic problem:
% Create a struct with default values
opt1 = bodeoptions;
% Change a value
opt1.MagScale = 'log'
% Now generate another (?) struct with the same options
opt2 = opt1;
% Change the value in the original struct back to default
opt1.MagScale = 'linear'
% Surprise! The value is changed back in the 'copy,' too
opt2.Magscale
Similarly, changing anything in opt2 changes opt1, too, so it appears opt2 is not another struct but a reference to the same structure as opt1.
Can anybody tell me what's happening here, and in particular: How would I create a copy of opt1 that I can change without changing opt1, too?

 Accepted Answer

Most likely, bodeoptions returns a handle class rather than a structure.
whos opt1
would tell you.
Matlab does not have a built-in way to do deep copy of handle classes. Possibly, the class has a method to do this. You can check with
methods(opt1)
But in any case, what's stopping you from creating your second variable with:
opt2 = bodeoptions;
It'll start out the same as opt1 but will be a different object.

6 Comments

whos returns
Name Size Bytes Class Attributes
opt1 1x1 plotopts.BodePlotOptions
Does that mean it's a handle?
What makes simply creating another structure and changing that one impracticable is that I change about 10 properties 8 or 9 of which I'd change in the second structure to the same values, so copying the original one would save a lot of code.
EDIT: methods(opt1) unearthed copyPlotOptions, so
opt2 = bodeoptions; opt1 = copyPlotOption(opt2, opt1);
has the expected behavior.
There's also copy_object_properties, so that
opt2 = bodeoptions; opt1 = copyPlotOption(opt1, opt2);
(note the changed order of the arguments) works, too.
opt1 is obviously an instance of a handle class. It is not a structure! See Object-Oriented Programming
It's definitively a class and from the behaviour, a handle class. You can check with
superclasses(opt1)
It will have handle in the list of superclasses.
As I said, check the methods of the class to see if it has a copy method. Otherwise, you could hack it by saving opt1 in a mat file and loading it again as opt2.
Actually, can you actually provide the output of
superclasses(opt1)
If it has matlab.mixin.copyable in the list, then
opt2 = copy(opt1); % or opt2 = opt1.copy()
will work.
Matlab is hiding something, or uses features, which are not yet documented. With R2013a
>> superclasses(opt1)
No superclasses for class plotopts.BodePlotOptions ...
With 2014a, I get
>> superclasses(opt1)
No class plotopts.BodePlotOptions
:(

Sign in to comment.

More Answers (1)

Very interesting. It doesn't happen with simpler structures you make on your own:
s1.a = 10;
s1.b = 20;
% Make copy.
s2 = s1
% Change something in the original.
s1.a = 999
% Print to command window;
s1
s2 % s2.a is not 999

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!