Passing options from subclass constructor to superclass?

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 件のコメント

Mohammad Sami
Mohammad Sami 2021 年 1 月 15 日
David Cardinal
David Cardinal 2021 年 1 月 15 日
Mohammad -- Thanks. That seems pretty close but doesn't quite work, at least the way I've applied it. I can turn the options struct into a cell array, but it fails when I try to pass it to another function. Maybe there is a missing pece where I have to redefine the function template for what it receives & turns into options?
Here is the error:
Invalid argument at position 4. Function requires exactly 3 positional input(s).
Mohammad Sami
Mohammad Sami 2021 年 1 月 15 日
Can you share the functions here.
Luna
Luna 2021 年 1 月 15 日
Did you try inputparser?
David Cardinal
David Cardinal 2021 年 1 月 15 日
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);

サインインしてコメントする。

 採用された回答

Matt J
Matt J 2021 年 1 月 15 日
編集済み: Matt J 2021 年 1 月 15 日

0 投票

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 件のコメント

David Cardinal
David Cardinal 2021 年 1 月 15 日
Matt -- If there isn't a bult-in way, then I think something like your code is probably needed. I tried to use your struct2pairs, but get an error since a cell array isn't what's expected. It seems like for optional values using arguments I need to actually stuff names & values directly into the call? I'm experimenting based on your code, but a lot of the nuances of matlab data types are still beyond me, so I haven't come up with anything that works yet.
David Cardinal
David Cardinal 2021 年 1 月 15 日
Matt -- just saw the edited version of your comment with how to use struct2pairs. It works great. Thanks!
David Cardinal
David Cardinal 2021 年 1 月 15 日
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 2021 年 1 月 15 日
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.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeArgument Definitions についてさらに検索

製品

リリース

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by