I am running into an infuriating problem with Matlab, and an earlier answer to apparently the same problem didn't help me, unfortunately. I apologize that the question is rather long - you need quite a bit of information to reproduce the problem (I tried to trim it as much as I could...)
The problem is this: No matter what I do, after I have used a class I cannot "make Matlab forget". Values used seem to be persistent, and edits to the class definition won't "stick". In the latter case, the error message is:
Warning: The class file for 'myClass' has been changed; but the change cannot be applied because objects based on the old class file still exist. If you use those objects, you might get unexpected results. You can use the 'clear' command to remove those objects. See 'help clear' for information on how to remove those objects.
I get that message even after
>> clear all
>> clear functions
>> clear ans
Somehow the class definition is persistent despite my attempts to clear it. To make matters worse, when I modify a value of an instance of the class, then clear it, the value is somehow not "forgotten". To illustrate, here is the source code of myClass
:
% a simple class definition that shows the problem that I cannot
% figure out how to redefine a class without restarting Matlab
classdef myClass < handle
properties
precursors = {'none'};
numPre = {1};
value = 1;
end
methods
function obj = myClass(pre, num, val)
% constructor
if nargin > 0
obj.precursors = pre;
obj.numPre = num;
obj.value = val;
end
end
function v = sumVal(obj)
% find the sum of the value of all precursors
n = numel(obj.precursors);
v = 0;
for ii = 1:n
pc = obj.precursors{ii};
if isa(pc, 'myClass')
if ii==1
v = 0;
end
v = v + sumVal(pc) * obj.numPre{ii};
else
v = obj.value;
end
end
end
end
% only the following named instances may exist:
enumeration
grandpa ({'none'}, {1}, 1)
father ({myClass.grandpa}, {3}, -1)
son ({myClass.father}, {2}, -1)
end
end
In a fresh instance of Matlab, I do the following:
>> son = myClass.son;
>> sumVal(son)
ans =
6
>> grandpa = myClass.grandpa;
>> grandpa.value = 5;
>> sumVal(son)
ans =
30
So far, so good. The sumVal
function discovers the fathers and grandfathers, and the sumVal
is computed correctly (6 * 1 in the first case, 6 * 5 in the second case).
Now I delete "everything" (I think):
>> clear all
>> clear functions
>> clear ans
And I create just one variable:
>> son = myClass.son;
Now comes the kicker - the unexpected answer
>> sumVal(son)
ans =
30
When I inspect the variables loaded, I find
>> whos
Name Size Bytes Class Attributes
son 1x1 112 myClass
There is no grandpa
instance, and the class definition file was not touched. Yet, the value of grandpa
(which I created, then deleted) is somehow persistent.
And when I make a small change to the myClass.m
file, and try to create a new variable (after a clear all
), I get the message shown above. All of which leads me to my question:
Where is Matlab hiding an instance of my class so that variables are persistent after a clear all
, and how do I clear the workspace (without restarting) so the class definition is "reset"?
I don't know if it matters, but I'm using Matlab 7.14.0.739 (R2012a)
You have an intermediate instance
myClass.father
that is not being destroyed by MATLAB. You have todelete
it yourselfEdit: Alternatively, you can add a destructor to your class
and use
delete(son)
instead of leaving it toclear
function to destroy. You can extend this to your case and recursively delete all instances in your tree.Those instances are "hiding" in the myClass enumeration class itself. Matlab is storing a reference to each of those named instances so when you reference them like
myClass.father
you get the same object back, instead of it constructing a new one. Probably similar to how values are stored inConstant
properties on classes.If you have any other classes that refer to the
myClass.xxx
enumerated instances inConstant
properties, enumerations, orpersistent
variables, they could also be holding on to references to them.Try doing
clear classes
a few times in a row instead of just once.To help debug this, you could put a couple debugging
printf()
statements in the constructor and destructor for this class, so you can see when the instances are really created and cleaned up.