I'm trying to reuse a package in which all classes are written using Class folder i.e all methods are files inside a folder @myclassname. I would like to read the members of the class object. In normal classdef classes, declaring a property public solves the problem. In my case, I didn't find any solutions and I don't want to rewrite the whole package.
Minimal example explaining my problem: simple class: \MatlabPath\@mytestclass\mytestclass.m
%myconstructor
function res =mytestclass()
st.a=1;
res=class(st,mfilename);
end
Current behavior:
>> obj=mytestclass();
>> obj.a
Access to an object's fields is only permitted within its methods.
Desired:
>> obj=mytestclass();
>> obj.a
ans =
1
Thank you
I know you don't want to rewrite the full package but if property access is important you might prefer that to the actual solution.
In the first MATLAB OOP classes, organised as you indicated (all methods in one folder), the programmer had to code their own subsref
and subsasgn
methods if they wanted customized access to their class properties.
I must say I did play a bit with it but quickly gave up as construction of simple classes was extremely tedious. MATLAB probably picked up on that and in later release introduced the new Classdef
model. Despite still having a few quicks (due to MATLAB passing almost everything by value), this Classdef
model is infinitely more convenient than the old formula.
If you want to stick with the old model, I can give you a minimalist example which will give you the desired behaviour. If you are only interested in exposing a few properties you can just replicate that a few times. If you plan to have all the properties of your package exposed, then I guarantee you that rewriting the package will be less effort than applying my solution to an extensive existing code base.
So in your folder : \MatlabPath\@mytestclass\
, you now need two files:
mytestclass.m
(I added a couple of different properties for example)
function res =mytestclass()
st.scalar = 1 ;
st.array = [1 2 3] ;
st.cellarray = {'1' '2' '3'} ;
res=class(st,mfilename);
end
and your own subsref.m
:
function out = subsref(obj,S)
thisS = S(1) ;
if strcmp(thisS.type , '.')
out = obj.(thisS.subs) ;
elseif strcmp(thisS.type , '{}')
% You might have to code this case too
elseif strcmp(thisS.type , '{}')
% You might have to code this case too
end
% recursive call if the struct S has more than one element
if numel(S) > 1
S(1) = [] ;
out = subsref(out,S) ;
end
end
Armed with that, you can now access your properties:
>> obj.scalar
ans =
1
>> obj.array
ans =
1 2 3
>> obj.cellarray
ans =
'1' '2' '3'
This minimal subsref
works for indexing into the arrays as well:
>> obj.array(2:end)
ans =
2 3
>> obj.cellarray(2)
ans =
'2'
And it also works for assignment:
>> obj.scalar = 125 ;
>> obj.scalar
ans =
125
>> obj.array(2:end) = [8 9] ;
>> obj.array
ans =
1 8 9
Keep in mind that this is a minimal example, some property type might not respond well to these simple cases, in which case you will have to add specific code to handle each particular case.