MATLAB Answers

royk
1

How to implement MyClass that overloads all methods of a certain naitive class ?

Asked by royk
on 25 Aug 2019 at 11:41
Latest activity Edited by Matt J
on 25 Aug 2019 at 23:05
I have a class MyClass that has a numerical property Val. I want the class to overload any/all numerical functions, such that fcn(Obj) returns fcn(Obj.Val).
I can implement separately an overload of any given function (say: sin, cos, and so), but I want a generic way to essentially overload ANY numeric function. Is there a way to do it?

  0 Comments

Sign in to comment.

2 Answers

Answer by Matt J
on 25 Aug 2019 at 16:35
Edited by Matt J
on 25 Aug 2019 at 16:41
 Accepted Answer

There is no special overloading method that allows this. However, you can diminish the tedious manual work of overloading all the methods by using a code writing tool like the following:
function writeOverloads(fcnlist)
for i=1:numel(fcnlist)
disp ' '
disp(char( "function varargout=" + fcnlist{i} + "(obj,varargin)" ));
disp ' '
disp(char( " [varargout{1:nargout}] = " + fcnlist{i} + "(Obj.Val,varargin{:})" ));
disp ' '
disp 'end'
disp '
end
With this, you just need to provide a list of the methods to be overloaded, and it will print the required code to the command window. Then, you can just copy/paste them to the classdef file. E.g,
>> writeOverloads({'sin','cos','log'})
will display,
function varargout=sin(obj,varargin)
[varargout{1:nargout}] = sin(Obj.Val,varargin{:})
end
function varargout=cos(obj,varargin)
[varargout{1:nargout}] = cos(Obj.Val,varargin{:})
end
function varargout=log(obj,varargin)
[varargout{1:nargout}] = log(Obj.Val,varargin{:})
end

  3 Comments

Also, you can autogenerate a decent initial list of all the numeric methods by doing,
fcnlist=methods('double')
royk's comment mistakenly posted as an answer moved here Use comments instead of starting new answers
thanks - much appreciated!
that will work indeed!
though I can't deny that it is a bit sad that the only way to do it is to end up with such a lengthy multi-function code...
@royk,
thanks - much appreciated! ... that will work indeed!
You're welcome, but please Accept-click the answer if it addresses your question.
though I can't deny that it is a bit sad that the only way to do it is to end up with such a lengthy multi-function code...
I did mention this issue in a Mathworks Usability Study about a year ago. So, they should be aware of it and hopefully are thinking about it. But I don't know what more efficient solution might be possible.
You could use Code Folding in classdef file to hide the generic overloads and keep the essential classdef code viewable. Just put all of the generic functions in their own methods block and collapse it.

Sign in to comment.


Answer by Guillaume
on 25 Aug 2019 at 13:07

You may want to derive your class from a built-in numerical type as explained here, this comes with all sorts of caveats (e.g. calling sin on your class will return the built-in type, not an object of your class) but it's the only way if you don't want to write your own overload for each function.

  2 Comments

royk's reply relocated here
Thanks! That's won't help unfortunately.
How does Matlab check if MyClass has a specific overloaded method for a given function Fcn ? Can I trick it, say by overloading ismethod to say true even if there method is not explicitly implemented ? And combine this perhaps with overloading subsref to implement a call to Obj.Fcn for any Fcn ?
How does Matlab check if MyClass has a specific overloaded method
Same way that any other OOP language does it, by looking at the list of functions explicitly defined by the class or any of its superclasses. It has nothing to do with ismethod and tricking ismethod wouldn't help at all for this.
In any OOP language, if you want a class to use the methods of another class, you derive from that other class. So, if you want to benefit of all the numeric functions, whatever they are, derive from a numeric type.
The other option is to recreate all these numeric functions in your class. Matt's method of generating them would certainly help, but in all likelyhood you'll still be missing a lots of functions found in various toolboxes. If you want to catch them all (including future, not yet existing, functions), again there's only one way: inheritance.
What certainly wouldn't work properly is overloading subsref. Granted, by overloading subsref you could write a check for dot indexing to see if what follows the dot is a method of a numeric type and invoke that method. However, the machinery would be complex (particularly if you've got your own methods, in particular private ones) and wouldn't help at all with the functional form of calling methods (i.e. you could catch myclass.sin, but not sin(myclass)).

Sign in to comment.