MATLAB Answers

Customize how my class is displayed as a property of any other class.

7 views (last 30 days)
Hi,
I wrote a custom datetime class, because built-in datetime is often too slow.
My class inherits from matlab.mixin.CustomDisplay so that I can modify how it displays in the terminal. In particular I want to modify how it shows up within the displaying of some (any) other class to which it is a property.
I.e. let there be a class x.m with a property
dtime (1,1) my.datetime = my.datetime(now)
Now, if I display an instance of x.m in the terminal, it will show something like:
x with properties:
dtime: [1x1 my.datetime]
...
What I want it to look like is
x with properties:
dtime: 08.03.2020 17:39
...
where that datestring corresponds to a (dependent) property of +my/datetime.m.
The built-in datetime does something like that! How I can achieve this??
Thanks,
Niko

  7 Comments

Show 4 older comments
Guillaume
Guillaume on 19 Mar 2020
Note, now that 2020a is out you should check it out, there's been some significant improvements to datetime, in particular to assignment and parsing. Mathworks timing tests show a 25x improvement on assignment and 1.75x improvement on parsing text.
Nikolaus Koopmann
Nikolaus Koopmann on 19 Mar 2020
oh really?! nice! this comes just in time.. i was about to rewrite A LOT of code back to datenums..
thanks!
Siddharth Bhutiya
Siddharth Bhutiya on 19 Mar 2020
As Guillaume mentioned, there have been some perfromance improvements to datetime/durations, specifically in subscripted assignment and text parsing in 2019b and 2020a. You can read about it here.
@Nikolaus If you could share some samples of performance bottleneck use cases that you mentioned, I can see if there are any improvements that can be made, so that you can avoid rewriting your exisinting code.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 9 Mar 2020
"I can make my class inherit from your mentioned parent classes, but i cannot view those classes.. so there is no way of finding out which method to overwrite i guess?"
First, I've never tried to override the display of classes as you want to do, so disclaimer: I've no idea if matlab.mixin.internal.MatrixDisplay allows you to do that or not.
Yes, there is a way of finding out all the methods of the class as well as their signature, attributes and names of inputs and outputs. There is however no way to see their source code so you still have to do a fair amount of reverse engineering.
mc = meta.class.fromName('matlab.mixin.internal.MatrixDisplay') %obtain reflection information of the class
mc.MethodList is an array of meta.method objects describing all the methods of the class (included private/protected/hidden methods). You can see that there is one abstract method disp (public, hidden) which takes two inputs helpfully named rhs1 and rhs2. You probably also need to override displayImpl (protected, hidden) which also takes two inputs.
Another disclaimer: The above is valid in R2019b. None of these classes are documented so they can change/disappear in the next version. If you have access to the R2020a pre-release, I'd strongly recommend having a look at the parent classes of datetime. Unfortunately, we're not allowed to discuss the pre-release.

  3 Comments

Nikolaus Koopmann
Nikolaus Koopmann on 9 Mar 2020
Hi Guillaume,
Thanks so much for your answer!
I tried your suggestions, but I have the feeling they are not the recipe for what I'm trying to achieve.
I mocked up an example
Consider class X like so:
classdef X < handle
properties
dt datetime
qdt qdatetime
qdts qdatetime
end
methods
function obj = X()
obj.dt = datetime(2000,1,1);
obj.qdt = qdatetime(datenum(obj.dt));
obj.qdts = [obj.qdt obj.qdt];
end
end
end
with class qdatetime like
classdef qdatetime < matlab.mixin.internal.MatrixDisplay
properties
num double
end
properties (Dependent)
asStr
end
methods
function obj = qdatetime(in)
obj.num = in;
end
function out = get.asStr(obj) % this is what i want to disp..
out = datestr(obj.num);
end
end
methods (Hidden)
function disp(obj,a1,a2)
disp('disp() called...')
end
end
methods (Access = protected,Hidden)
function displayImpl(obj,a1,a2)
disp('displayImpl called...')
end
end
end
now look at this
>> x=X
x =
X with properties:
dt: 01-Jan-2000
qdt: [1×1 qdatetime]
qdts: [1×2 qdatetime]
>> x.qdt
ans =
qdatetime
displayImpl called...
>> x.qdts
ans =
1×2 qdatetime array
displayImpl called...
>> qdatetime.empty()
ans =
0×0 empty qdatetime array
disp() called...
interestingly i can get disp() to get called only when i create an empty qdatetime array..
i want x.qdt to be represented similiar to how x.dt is displayed when I enter x into the console..
so instead of
x =
X with properties:
dt: 01-Jan-2000
qdt: [1×1 qdatetime]
qdts: [1×2 qdatetime]
i want
x =
X with properties:
dt: 01-Jan-2000
qdt: 01-Jan-2000
qdts: [1×2 qdatetime]
So I want the dep. prop. asStr to replace [1×1 qdatetime]
I'm sure you get what i want ... :)
Thanks
-Niko
Guillaume
Guillaume on 10 Mar 2020
Indeed, after some testing it doesn't appear that this kind of display is implemented by matlab.mixin.internal.MatrixDisplay. In fact, I'm not sure what kind of display it implements.
I've modified your original X to:
classdef X < handle & matlab.mixin.CustomDisplay
properties
dt datetime
qdt qdatetime
qdts qdatetime
end
methods
function obj = X()
obj.dt = datetime(2000,1,1);
obj.qdt = qdatetime(datenum(obj.dt));
obj.qdts = [obj.qdt obj.qdt];
end
end
methods (Access = protected)
function displayScalarObject(this)
displayScalarObject@matlab.mixin.CustomDisplay(this);
end
end
end
and by setting a break point in the displayScalarObject method, you can then step through what is happening during the display. In particular, you can see which datetime methods are called. There's only two methods that are called, the datetime.size method, which is normal it also happens with qdatetime and the datetime.cellstr method which is unexpected. Unfortunately, even if you implement a qdatetime.cellstr it doesn't get called automatically. This leads me to believe that the display of datetime within objects is actually hardcoded in matlab, so I'm afraid that it doesn't look like there's any way to implement the same.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!