A class to simulate missing arguments in function calls
Show older comments
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 Comments
Steven Lord
on 7 Feb 2020
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
on 7 Feb 2020
Stephen23
on 7 Feb 2020
Rather than reinventing the wheel, you could just use standard MATLAB ways to handle this:
Accepted Answer
More Answers (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
on 7 Feb 2020
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 Comments
Daniele Busi
on 10 Feb 2020
Edited: Daniele Busi
on 10 Feb 2020
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
on 11 Feb 2020
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!