Passing options from subclass constructor to superclass?

28 views (last 30 days)
I really like the new "arguments" way to pass values, including optional values. However, one really nice feature of the (old?) varargin approach was that you could just pass the whole thing along. But with arguments, if I have a subclass that only needs a couple options and is happy to pass the rest to its superclass, I don't see a great way to do that. I've found that I need to specifically implement every option and pass them specifically. I'm probably missing something, but would love to learn what. Thanks! -- David
  5 Comments
David Cardinal
David Cardinal on 15 Jan 2021
We have been using inputparser, but I really like the (newer?) arguments syntax as I think it both easier to write & read. This is the first glitch I've run into with it. Below is an example. This is a function in a sub-class that takes some options and then calls the superclass version of the function. I'd like to simply be able to pass along the options structure
function ourPicture = TakePicture(obj, aCIScene, intent, options)
arguments
obj;
aCIScene;
intent;
options.numHDRFrames = 3;
options.numBurstFrames = 3;
options.imageName char = '';
options.reRender (1,1) {islogical} = true;
end
...
ourPicture = TakePicture@ciCamera(obj, aCIScene, intent, options);;
end
And here is the method in the super-class (which can also be called directly, so I assume needs to support a similar function templae:
function ourPicture = TakePicture(obj, aCIScene, intent, options)
%TakePicture Main function telling us to create a photo
arguments
obj;
aCIScene;
intent;
options.numHDRFrames = 3;
options.imageName char = '';
options.reRender (1,1) {islogical} = true;
options.expTimes = [];
end
...
The call from the sub-class fails with the below error. The only way I've figured out to get it to work is to manually recreate the A/V pairs and pass them, which seems pretty ugly:
Invalid argument at position 4. Function requires exactly 3 positional input(s).
ourPicture = TakePicture@ciCamera(obj, aCIScene, intent, options); %'reRender', options.reRender);

Sign in to comment.

Accepted Answer

Matt J
Matt J on 15 Jan 2021
Edited: Matt J on 15 Jan 2021
Can't you just convert the options structure back to a cell array of name value pairs and use that to call the super class constructor? Using the attached function struct2pairs, this would be
function ourPicture = TakePicture(obj, aCIScene, intent, options)
arguments
obj;
aCIScene;
intent;
options.numHDRFrames = 3;
options.numBurstFrames = 3;
options.imageName char = '';
options.reRender (1,1) {islogical} = true;
end
...
varargin=struct2pairs(options);
ourPicture = TakePicture@ciCamera(obj, aCIScene, intent, varargin{:});;
end
  4 Comments
David Cardinal
David Cardinal on 15 Jan 2021
BTW, it turns out that I'd found a built-in function, namedargs2cell(), that does a very similar thing to struct2pairs, but I hadn't made the connection to using it with varargin. I think it also works when used with your sample code. Thanks again!
David Cardinal
David Cardinal on 15 Jan 2021
Another handy feature for arguments is the .?<classname> option, which automatically generates a structure with properties from <classname> that might have been passed in, which can in turn be passed to namedargs2cell (or struct2pairs) and in turn as a "varargin" parameter to that class.
Overall, I'm liking this approach better than inputparser(), especially when created classes and sub-classes with lots of optional parameters.

Sign in to comment.

More Answers (0)

Categories

Find more on Argument Definitions in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!