Argument validation for class methods

27 次查看(过去 30 天)
Is there a best practice for validating (or not validating) the 'self' arguments in class method definitions?
Consider:
classdef my_class < handle
properties
A;
end
methods
function obj = my_class
obj.A = 0;
end
function add_to_obj(obj, B)
arguments
obj my_class; %This seems unnecessary
% obj; %Alternately we could omit the 'class' specifier
B (1,1) double;
end
obj.A = obj.A + B;
end
end
end
The class specification of the obj argument seems superflous and should be self-evidently true. Are there performance implications for leaving it in there (i.e., if I'm calling add_to_obj a lot)? Should I just leave out the specifier (essentially bypassing the argument validation)?

采纳的回答

Steven Lord
Steven Lord 2024-7-11
The class specification of the obj argument seems superflous and should be self-evidently true.
Not necessarily. The first input argument to a class method is not always required to be an instance of that class! There are two common patterns where this may not be the case. Let's take a sym object as an example.
syms x
This command calls the plus method for the sym class, as we can tell using the which function.
y = x + 1
y = 
which('plus(x,1)')
/MATLAB/toolbox/symbolic/symbolic/@sym/plus.m % sym method
This also calls the plus method for the sym class, even though 1 is not a sym. It doesn't call the plus defined for double arrays.
z = 1 + x
z = 
which('plus(1, x)')
/MATLAB/toolbox/symbolic/symbolic/@sym/plus.m % sym method
which('plus(1, 2)')
built-in (/MATLAB/toolbox/matlab/ops/@double/plus) % double method
Another common pattern is when class precedence is involved. [I suppose the example above simplifies down to this as well, since as stated on that documentation page double is always inferior to classes defined using classdef, which is the case for the sym class.] The graph object in MATLAB has an overloaded plot method that can accept an axes handle as its first input.
g = graph(bucky);
ax = axes;
plot(ax, g)
Despite the first input to plot being an axes object, MATLAB calls the graph plot method.
which('plot(ax, g)')
/MATLAB/toolbox/matlab/graphics/math/@graph/plot.m % graph method
This is because the graph class states that the axes class (technically matlab.graphics.axis.Axes) is one of its InferiorClasses (as listed in the metaclass information.) So if both a graph object and an axes object are in a method's argument list, regardless of the order in which they're listed in that argument list, we call graph's method.
q = ?graph;
{q.InferiorClasses.Name}.'
ans = 2x1 cell array
{'matlab.graphics.axis.Axes'} {'matlab.ui.control.UIAxes' }
class(ax)
ans = 'matlab.graphics.axis.Axes'
But to get back to your question about performance, measure it and find out! You'll probably want to use timeit or the Profiler as I suspect the impact with and without the validation is going to be so small tic and toc may not capture it. I strongly suspect that unless your method is very fast (returning a constant value) this probably isn't going to be your bottleneck.
  3 个评论
Steven Lord
Steven Lord 2024-7-11
I used the plus function / method in my example, but your add_to_obj(obj, B) method looks like it is adding together obj and B, doesn't it? So it could be called plus, couldn't it?
Please contact Technical Support directly using this link to submit an enhancement request for mustBeEmptyOrA. When you do, please describe your use case (especially how the lack of it proves to be a problem when you distribute your code.) The developers benefit greatly when designing new features if they have real-world usage stories to help them consider design trade-offs.
John
John 2024-7-11
My example was really just intended as a minimal demonstration. The real applications were quite different. But thanks nontheless. I'll put in a enhancement request, as you suggest.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Argument Definitions 的更多信息

产品


版本

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by