Open paulbareilCodotek opened 2 years ago
Honestly, I have no idea. Transplant doesn't do anything crazy, though: It calls subsasgn on the object, nothing more.
Does your class work with subsasgn
?
I was able to debug the Python and Matlab code. I haven't found the exact source of the problem yet, still trying to wrap my head around the way it works. But from what I understand, the problem is the 'del proxy'
The python code below calls matlab with the substruct function to get the structure necessary to make the call, then the subsasgn makes the call correctly and somewhere in the process, on the Matlab side, a new proxied_objects object is created at the last cell array index.
access = MatlabStruct(self.process.substruct('.', name))
self.process.subsasgn(self, access, value)
That new proxied_object is correct. It has the changed value. However, when the following function is called, the object we just created and modified is deleted.
def __del__(self): self.process._del_proxy(self.handle)
I do not know yet why the del function is called and why a new proxied_objects is created instead of being modified, but the problem lies there. It also explains why a copyable mixin class has no problem since the copy is shallow.
Got it. The self.process.subsasgn(self, access, value)
line actually returns the new modified object. As in the Matlab object we have to return the object itself.
function obj = set.attribute(obj, value)
`obj.attribute = value;
end`
While, when subclassing < matlab.mixin.Copyable
there is a warning saying "Set function in handle class does not need to return the modified object."
So the actual modified object is discarded right now, but when trying this directly in Matlab it seems to automatically reapply the object.
It is actually a big problem because if I create an object testObject = TestObject()
and then re-use that object accross different other objects, none of them will see the change because a different copy would have been created.
Do you see any way to go around this? Other than < matlab.mixin.Copyable
I mean?
Thank you for your analysis! That sounds like a nasty problem. If I understand you correctly, Copyable
classes behave differently than non-Copyable
classes to subsasgn
.
I think we would have to (conditionally?) overwrite self.process
in __setattr__
. Can we do that in every case, or only for one of the Copyable
/non-Copyable
?
In either case, I'm afraid I don't have access to Matlab any longer, which means I can't test any changes myself. But I'll happily review and accept a pull request!
Yes that seems to be the case. I will investigate a little further on the Matlab side to be sure to understand the problem correctly. You built such a good package, I feel like I have to contribute a little if I can. I do not have much time, but will come back on this.
ok, I made some quick Matlab tests If you have the following class in Matlab
`classdef TestObject
properties
attribute = 123456;
ref_obj;
end
methods
function obj = set.attribute(obj, value)
obj.attribute = value
end
function obj = set.ref_obj(obj, value)
obj.ref_obj = value
end
function obj = TestObject(value)
obj.attribute = value;
end
end
end`
Then if you create 2 objects and reference it on the second object
test = TestObject(1); test2 = TestObject(2); test2.ref_obj = test;
If you do test.attribute = 10; test2.ref_obj will return 1
!!!. So the problem is NOT transplant.
It seems Matlab "standard" classes cannot be referenced! Making it inherit copy was not a requirement, it need at least to inherit from "handle" to work as a referenceable class. https://www.mathworks.com/help/matlab/handle-classes.html
Oh, Matlab! I do wonder what considerations and constraints have lead to the maze of curveballs that is the Matlab object system.
At any rate, thank you for sharing your analysis. I find it oddly satisfying to dive deeply into strange code such as Matlab's.
Hi, I cannot set attributes if the class does not import mixin. The following matlab TestObject is in a @TestObject folder and TestObject.m file. I can create an instance of this class in Matlab and change the attribute. I can do:
test = TestObject(2); and if I print test.attribute, it returns 2. If I then do test.attribute = 3;, it will change its value.
However, doing this in Python does not work. The values stays at 2. If I change the Matlab class header to
classdef TestObject < matlab.mixin.Copyable
, then it works. However, I need to interface to matlab code that does not implement the mixin class. How can I change the attribute of the Matlab class then?