Operator overloading did not work for a second operand if the first operand has no operator overloading

I create two classes, DataSet and Transformation. The class Transformation has the operator & overloaded.
classdef Transformation
methods
function obj = and(A,B)
% do something
end
end
classdef DataSet
methods
%...
end
Now i can call
X = Dataset();
Y = Transformation();
Z = Y & X;
but not
Z = X & Y; % ERROR: no and() operator for X
Matlab uses the function of the most left operand if both classes have the same precedence and both have a function with the same name. But in this example there is just one class with the and() function. Why can't Matlab use the and() function of the second operand if there is no and() function in the first operand?
(I tried to use the classdef (InferiorClasses = {?class1,...} attributes, but with this solution i have to add every DataSet class to every Transformation class because these attributes don't inherit. Too much work and it can lead to errors if someone forget same classes in this list.)

Answers (2)

Why MATLAB couldn't have been designed to look for the first class that defines a method, I can't say. However, I wonder if this has to be a huge inconvenience. Somewhere in your code, the operation
Z=X&Y
is going to have to determine the class of X and figure out how to process it appropriately. You seem to want to do that work in and@Transformation, but why not do it in and@DataSet and then make a generic call to and() within that?
Or, assuming your AND operations are going to be commutative, you could just add a simple AND method to class DataSet which inverts the order of the operands
function Z=and(X,Y) %in classdef DataSet
Z=and(Y,X); %This calls the AND method of class Y, whatever that is.
end

12 Comments

Why MATLAB couldn't have been designed to look for the first class that defines a method, I can't say.
If I call
set(HandleGraphicsHandle, 'userdata', DataSetObject)
then I would be unlikely to want DataSet's set() method to be called.
Not sure. HandleGraphicsHandle defines a set() method, so it would still take precedence. The OP's proposal was that the precedence rules simply ignore arguments that don't define a version of the method.
When I wrote HandleGraphicsHandle, I was referring to those double() values, not to handle() of them. There is no set() for double() or char()
OK, but then I'm not understanding the example. In your example, the set method of DataSet will in fact be called if DataSet defines one. Try the following
>> clear classes; h=figure; set(h,'UserData',myclass)
Error using myclass/set
Too many input arguments.
where
classdef myclass
methods
function set(obj)
disp 'Wrong'
end
end
end
When you mention a class name, you are invoking the constructor for it, no matter what methods it has. That is why I wrote DataSetObject, to indicate an object of DataSet class (e.g., the X of the original posting)
Not sure why that's relevant. My example also applies when an object is passed.
>> x=myclass; h=figure; set(h,'UserData',x)
Error using myclass/set
Too many input arguments.
How odd. If you change the method to varargin will it proceed to the 'Wrong' ?
This is really weird .. yes, it proceeds to the 'Wrong' ... (?!)
Perhaps it's a little inconvenient, but the behavior does obey the documentation. I guess that means that if you want to store user-defined objects as user data, you have to do things like this
set(h,'UserData',{x}), %encapsulate in cell
@Matt J: If I use a AND() method in my DataSet class which inverts the operands, this can be dangerous. A user of the class could accidentally write X & X and this would be an infinit loop.
If your intention was to allow users to do X&X, it is unclear why you don't have an AND method in DataSet already. You're going to need such a method if for no other reason than to define X&X.
If it is not your intention to enable X&X, but you're worried about users doing it as a typo, only a simple modification is required to prevent the infinite loop,
function Z=and(X,Y) %in classdef DataSet
if isa(X,'DataSet') & isa(Y,'DataSet'), error 'Improper operation'; end
Z=and(Y,X);
end
It doesn't even matter that much if you do avoid the infinite loop. MATLAB will time out when its recursion limit is reached. One way or another, the user will get an error message.
If I add a AND() method to my DataSet class I have a stronger connection from DataSet to Transformation.
Not true. My proposal for and@DataSet makes no reference to Transformation at all!

Sign in to comment.

Thx for the help.
@Matt J: If I use a AND() method in my DataSet class which inverts the operands, this can be dangerous. A user of the class could accidentally write X & X and this would be an infinit loop.
I try to avoid adding another AND() method to the DataSet class because I want to keep the Transformation logic as local as possible. If I add a AND() method to my DataSet class I have a stronger connection from DataSet to Transformation. If I just want to use the DataSet class in another project, it would bring the Transformation class with it. But i can't see a better solution at the moment.
Is there a reason for ignoring the second (right) operand if the first (left) operand has no convenient method?

Products

Asked:

on 27 Mar 2013

Community Treasure Hunt

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

Start Hunting!