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 comentarios

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).
Can you share the functions here.
Luna
Luna el 15 de En. de 2021
Did you try inputparser?
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);

Iniciar sesión para comentar.

 Respuesta aceptada

Matt J
Matt J el 15 de En. de 2021
Editada: Matt J el 15 de En. de 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 comentarios

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.
Matt -- just saw the edited version of your comment with how to use struct2pairs. It works great. Thanks!
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!
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.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Argument Definitions en Centro de ayuda y File Exchange.

Productos

Versión

R2020b

Preguntada:

el 14 de En. de 2021

Comentada:

el 15 de En. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by