A class to simulate missing arguments in function calls
显示 更早的评论
My goal is to design a class named "Unknown", that simulates missing arguments in function calls.
For example, this script
fun(Unknown)
function fun(a)
a %or any other line of code that includes the "a" variable
end
should produce an error in the same way this script does
fun()
function fun(a)
a %or any other line of code that includes the "a" variable
end
Is there any way of achieving this?
My current, hopeless ideas:
- Overload some sort of "caller" function in the Unknown class to prevent any MATLAB function to be called on an Unknown object - if that "caller" function exists
- Apply some strange property to the Unknown class that does what I want
3 个评论
Steven Lord
2020-2-7
Why are you trying to do that? How do you plan to use this "Unknown" class if you can create it?
There are other techniques that you could use if you want to "skip" an argument (one such technique is to specify the argument as [] and having the function check if it was called with [] as one of its inputs.)
Daniele Busi
2020-2-7
Stephen23
2020-2-7
Rather than reinventing the wheel, you could just use standard MATLAB ways to handle this:
采纳的回答
更多回答(3 个)
Seems to me that you can effectively accomplish what you want by defining a trivial class with no properties or methods,
classdef Unknown
end
Now, pretty much everything you try to do with the class within a function call will raise an error, e.g.,
>> fun=@(a,b,c,d) a+b+c+d;
>> fun(1,Unknown,3,4)
Undefined operator '+' for input arguments of type 'Unknown'.
Error in @(a,b,c,d)a+b+c+d
Steven Lord
2020-2-7
So you want your function to be able to accept 0, 1, 2, 3, or 4 input arguments? In that case you probably want varargin.
function x = addThemUp(varargin)
narginchk(0, 4) % Error if addThemUp is called with < 0 inputs (impossible) or > 4 inputs
x = sum([varargin{:}]);
end
or if you want to do this with +:
function x = addThemUp(varargin)
narginchk(0, 4) % Error if addThemUp is called with < 0 inputs (impossible) or > 4 inputs
x = 0;
for whichone = 1:nargin
x = x + varargin{whichone};
end
end
Let's try this with a couple sets of inputs:
>> addThemUp(1, 2, 4)
ans =
7
>> addThemUp(1, 2)
ans =
3
>> addThemUp()
ans =
0
>> addThemUp(1, 2, 3, 4, 5)
Error using addThemUp (line 2)
Too many input arguments.
The main drawback is that one must always use myfeval, which is not very readable.
Yet another solution, which might address that, is to create your own class of function handles,
classdef Unknown
end
classdef SmartFun %class for functions with prechecks
properties (Constant)
builtins=smartBuiltins;
end
properties
fHandle
end
methods
function obj=SmartFun(fHandle) %constructor
obj.fHandle=fHandle;
end
function varargout=subsref(obj,S)
switch S.type
case '()'
SmartFun.check_for_unknowns(S.subs{:});
[varargout{1:nargout}]=feval(obj.fHandle,S.subs{:});
otherwise
error 'Undefined indexing operation'
end
end
end
methods (Static)
function check_for_unknowns(varargin)
map=cellfun(@(c)~isa(c,'Unknown'),varargin);
assert(all(map),'Unknown variable type entered');
end
end
end
function safecall=smartBuiltins
m=methods('double');
for i=1:numel(m)
safecall.(m{i})=SmartFun(str2func(m{i}));
end
end
and now you can do things like
>> fun=SmartFun( @(a,b,c,d) a+b+c+d );
>> fun(1,2,3,4)
ans =
10
>> fun(1,2,Unknown,4)
Error using SmartFun.check_for_unknowns (line 32)
Unknown variable type entered
Error in SmartFun/subsref (line 17)
SmartFun.check_for_unknowns(S.subs{:});
3 个评论
Daniele Busi
2020-2-10
编辑:Daniele Busi
2020-2-10
Unfortunately, I think you are right. Matlab does not currently provide a mechanism that lets an object implicitly call a method when it is passed to a function as an argument. The closest thing to that, I think would be subsindex, but that is for indexing expressions, not function call expressions. Therefore, I don't think there is a way to you have what you want with the exact syntax you want.
However, some of the issues you cite above can be mitigated by adding a Constant property to SmartFun, as in my recent edit. This gives a way to pre-instantiate all the methods of class double as SmartFun objects and use them with a more readable, Python-like syntax:
>> safecall=SmartFun.builtins;
>> safecall.atan2(1,1)
ans =
0.7854
>> safecall.sind(90)
ans =
1
>> safecall.sqrt(Unknown)
Error using SmartFun.check_for_unknowns (line 35)
Unknown variable type entered
Error in SmartFun/subsref (line 20)
SmartFun.check_for_unknowns(S.subs{:});
Daniele Busi
2020-2-11
类别
在 帮助中心 和 File Exchange 中查找有关 Data Type Identification 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!