From: Eric Salemi on
Hi,

I'm using Matlab 7.0.1.246 (R14) to develop a large project. I notice a weird bevahior when using the OOP framework of Matlab and would like to have an opinion.

I have a simplistic user-defined class on my path class MyClass. In the @MyClass folder, I placed the constructor MyClass.m and the overloaded subsasgn.m:

-- MyClass.m --

function this = constructor(varargin)

this = class(struct,'MyClass');

-- end of MyClass.m --

-- subasgn.m --

function this = subsasgn(this,index,varargin)

keyboard

-- end of subasgn.m --

Then, on the matlab prompt I build a 1x2 MyClass object, and try to do an assignment:

obj = [MyClass MyClass];
[obj.field] = deal(true); % GO IN DEBUG MODE
[obj.field(:)] = deal(true); % SEGMENTATION FAULT

Matlab purely crash with a segmentation fault on the second assignment.

If I remove the subsasgn.m method, I get a normal error message. If I overload numel and force it to return 1 instead of 2, Matlab enters the overloaded subasgn.m. It seems that Matlab crashes after the call to numel.m but before it enters the overloaded subasgn.m.

Anyone knows what could go wrong?
From: Matt J on
Have you overloaded subsref as well? In particular, what happens when you type

[obj.field(:)]

without trying to assign it to anything (and without overloading numel)?
From: Eric Salemi on
> Have you overloaded subsref as well?

I tried to overload subsref as well, I guess Matlab needs [obj.field(:)] to return something in order to compute the number of expected arguments for the subsequent subasgn call.

The builtin version of subasgn does not accept array-reference operation on multiple output, so I have to implement it myself:

-- subsref.m --

function varargout = subsref(this,index)

n = numel(this);

if n > 1
varargout = cell(1,n);
for i = 1 : n
varargout{i} = subsref(this(i),index);
end
else
varargout = { builtin('subsref',this,index) };
end

-- end of subsref.m --

I also modified the constructor to include a field member:

-- MyClass.m --

function this = constructor(varargin)

this.field = 1:4;

this = class(this,'MyClass');

-- end of MyClass.m --

Now I obtain:

>> obj = [MyClass MyClass];
>> [r1 r2] = obj.field(:)
r1 =
1
2
3
4
r2 =
1
2
3
4

The weird thing is that now I obtain the following results:

obj.field(1) = 0; % ENTER SUBASGN.M (WEE!)
[obj.field(1)] = deal(0) % SEGMENTATION FAULT

The first assignment is not correct according to me since there should be 2 input arguments, however matlab does enter the subasgn.m overloaded method. The second assignment, which looks correct does crash.

I feel it's going in the right direction, but I'm still puzzled.
From: Steven Lord on

"Eric Salemi" <eric.salemi(a)septentrio.com> wrote in message
news:htobje$6kq$1(a)fred.mathworks.com...
> Hi,
>
> I'm using Matlab 7.0.1.246 (R14) to develop a large project. I notice a
> weird bevahior when using the OOP framework of Matlab and would like to
> have an opinion.
>
> I have a simplistic user-defined class on my path class MyClass. In the
> @MyClass folder, I placed the constructor MyClass.m and the overloaded
> subsasgn.m:

*snip*

> Then, on the matlab prompt I build a 1x2 MyClass object, and try to do an
> assignment:
>
> obj = [MyClass MyClass];
> [obj.field] = deal(true); % GO IN DEBUG MODE
> [obj.field(:)] = deal(true); % SEGMENTATION FAULT
>
> Matlab purely crash with a segmentation fault on the second assignment.

Please send the crash log file created when MATLAB throws the segmentation
fault along with your class code and these lines of code with which you can
reproduce the problem to Technical Support for investigation. [I know
you've already posted your class code and reproduction steps here, but I
want Technical Support to have the whole picture available in their case
file.]

--
Steve Lord
slord(a)mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ
To contact Technical Support use the Contact Us link on
http://www.mathworks.com


From: Eric Salemi on
As a side note, I realized that typing "obj.field" does trigger an call to numel but "obj.field(...)" will not. This is just random guessing, but wouldn't it affect dramatically the way Matlab internally computes the number of output arguments to "deal" in the following cases:

[obj.field] = deal(...) << NARGOUT = 2
[obj.field(...)] = deal(...) << NARGOUT = 1, since numel is *not* called

For builtin types, it does not matter since issuing "obj.field(...)" on a non-scalar obj object result in an error before the output argument counting even occurs. But for user-defined objects, it means that a possibly overloaded numel.m would simply never be called, right? In that case the number of output has to be wrongly computed and that would perhaps explain the weird crashes.