# Loren on the Art of MATLAB

## Deconstructing Destructors

I'm pleased to introduce guest blogger Jennifer Black, manager of the MATLAB object system team. Today Jennifer will be sharing some thoughts on what happens when objects are destroyed in MATLAB and how you can control aspects of this process.

### Contents

#### Why Define a Destructor

When an instance of a class is cleared, MATLAB automatically cleans up the values of the properties owned by that object. For example, if I have a Signal class with a property that stores a matrix of double values, that matrix is destroyed when a Signal is destroyed. Sometimes, however, additional actions might be needed to handle external resources.

Let’s consider the following class:

type FileReader1

classdef FileReader1 < handle
properties
FileID
end
end



In MATLAB, a file identifier is an integer returned by the fopen function. It is used by file I/O functions such as fread and fwrite to access the file. If fopen cannot open the file, it returns -1.

If I have an open FileReader named reader in my workspace, clearing reader will cause MATLAB to clear the value stored in my FileID property. Now the number is gone, but the file is still open. Clearing FileID without first closing the file means the file is left open even though it is no longer being used. If this happens enough times I might run out of system file handles.

Let's look at defining a destructor to close the file handle. A destructor is a method of a class responsible for cleaning up resources owned by objects. In MATLAB, the handle superclass is used for all kinds of objects that have a unique identity independent of their current state. Unlike numbers, matrices, etc., handle objects represent unique things that have a beginning and an end and may change internal state along the way. Any subclass of handle may define a special method named delete, often referred to as a destructor. In the case of my FileReader class, I can correct the problem of leaking file handles by implementing my own destructor:

type FileReader2

classdef FileReader2 < handle
properties
FileID
end
methods
function delete(readerObj)
fclose(readerObj.FileID);
end
end
end



#### Defining a Destructor

A MATLAB destructor takes a single input argument - the object being destroyed - and returns no outputs. The input object is always scalar even if an array of MATLAB objects goes out of scope all at once.

In a MATLAB class you can define a method named delete that is not a destructor. A delete method with a different signature is not a destructor, nor is a static delete method. For example, defining the method to take more than one input argument or to return any output arguments means the method is not treated as an object destructor.

#### Calling Destructors

An object destructor can be called either explicitly by calling the delete method, or implicitly by MATLAB, for example when a variable is cleared or goes out of scope. Let's consider the difference between these two actions. To do so I will add a constructor and a readData method to my class:

type FileReader3

classdef FileReader3 < handle
properties(SetAccess = protected)
FileID = -1;
FileName
end

methods
function reader = FileReader3(fname)
if ischar(fname)
reader.FileName = fname;
reader.FileID = fopen(fname,'r');
end
end

function colorData = readData(reader)
if reader.FileID == -1
error('No file name has been specified for this FileReader.  No data will be read.');
else
colorData = fscanf(reader.FileID,'%f',[3,inf]);
colorData = colorData';
frewind(reader.FileID);
end
end

function delete(reader)
if reader.FileID ~= -1
s = sprintf('Closing %s', reader.FileName);
disp(s);
fclose(reader.FileID);
end
end
end
end



First, let's consider the case where I have one variable holding a FileReader:

myReader = FileReader3('colorData.txt');


Explicitly calling delete on myReader invokes the destructor and then destroys the FileReader. The myReader variable remains in my workspace, but its handle is no longer valid:

delete(myReader);

Closing colorData.txt

isvalid(myReader)

ans =
0


An implicit call to a destructor will occur if I clear myReader from my workspace:

myReader = FileReader3('colorData.txt');
clear myReader

Closing colorData.txt


The destructor will also be implicitly called if my variable goes out of scope, for example because the end of a function has been reached. To illustrate, let's add a helper function in which I create a FileReader:

type readDataFromFile

function colorData = readDataFromFile(filename)
myReader = FileReader3(filename);
colorData = readData(myReader);
end


When I call my new helper function, myReader is created in the function and will go out of scope when the function ends. This causes MATLAB to clear the variable, which results in an implicit call to the delete method:

colordata = readDataFromFile('colorData.txt');

Closing colorData.txt


Now, let's contrast what we have just discussed about having a single handle with the case where I have multiple handles to the same FileReader. This happens, for example, when I create a handle object and then assign that handle to another workspace variable:

reader1 = FileReader3('colorData.txt');
reader2 = reader1;


With these two handles to the same FileReader now in my workspace, I will explicitly call delete, and then use the isvalid method to see what happened to the FileReader object:

delete(reader1);

Closing colorData.txt

isvalid(reader1)

ans =
0

isvalid(reader2)

ans =
0


As expected, the reader1 handle is no longer valid, but note that reader2 is also no longer valid. Why did this happen? Because when I explicitly call delete, the destructor is called and the object is destroyed no matter how many handles there are referencing that object.

Now let's see what happens when a destructor is called implicitly. Once again let's create two handles to the same FileReader:

reader1 = FileReader3('colorData.txt');
reader2 = reader1;


But this time, rather than call the destructor explicitly, I will just clear one of the handles. As we saw earlier, this can result in an implicit call to the delete method:

clear reader1;
isvalid(reader2)

ans =
1


Why is reader2 still valid, and why was my destructor not called? Because MATLAB will only implicitly call a destructor when the last reference to an object is cleared. As reader2 still exists in my workspace, the underlying FileReader is not destroyed.

Most often a destructor is defined as a public method, but it can also be declared as a private or protected method. Making it private will prevent code outside the class from explicitly calling the destructor. Similarly, a protected destructor can only be explictly called from methods of the same class or from subclass methods. MATLAB will always be able to implicitly call a destructor, even one declared private or protected. You might choose to restrict access to your destructor in a situation where you want to prevent the accidental deletion of an object, such as when you have a singleton object.

#### Handles Contained within Other Structures

What happens when a handle is stored as a field of a struct or a cell of a cell array, or as a property of another object? When that top-level container variable is destroyed, the handle object will also be destroyed and its delete method implicitly called if and only if no other references to the object exist. Let's look at an example with structs:

s.myReader = FileReader3('colorData.txt');
clear s

Closing colorData.txt


Note that the FileReader stored in the myReader field of s has been destroyed. However, as we saw previously, another handle to the same FileReader will prevent the destruction of the object:

reader4 = FileReader3('colorData.txt');
s.myReader = reader4;
clear s
isvalid(reader4)

ans =
1


Even after clearing s, we see that reader4 is still valid. The second handle prevented the implicit destruction of the object.

#### Classes in Hierarchies

So far we have been looking at examples of stand-alone classes, but what about classes that are part of a hierarchy? In MATLAB, every class has the ability to control its own destruction behavior. In a hierarchy of classes, every class can define its own destructor. As a result, a destructor cannot be defined as a Sealed method.

When an object is destroyed, MATLAB will call the destructor of the class of the object first, if it has been defined. Next, the destructor of each superclass is called, starting with the most direct superclass.

A destructor can reference the properties of the class itself, including properties inherited from superclasses, but it generally should not reference properties of a subclass. Why? Because when a superclass destructor is executing, the destructor of its subclass has already executed, and could have invalidated the values in its properties.

#### How Do You Use Destructors?

Now that we've discussed the basics of working with destructor methods in MATLAB, I'd like to hear of your experiences. Are you already using destructors? If you have any interesting applications or questions, I'd be very happy to hear about them here.

Get the MATLAB code

Published with MATLAB® R2013a

### 5 Responses to “Deconstructing Destructors”

1. Sven replied on :

Loren, see the 4 lines of code above the text “Even after clearing s, we see that reader4 is still valid. The second handle prevented the implicit destruction of the object.”

In these lines, you make a reader, assign a (handle) copy of it, and then clear that handle copy. As you write above, “the second handle prevented the implicit destruction of the object”. HOWEVER, the output from that code chunk contains “Closing colorData.txt”, which indicates that the destruction method _was_ called. I’m confused.

Similarly, you have the two lines:

reader1 = FileReader3(‘colorData.txt’);
reader2 = reader1;

which somehow ran the destructor method because it produced the output “Closing colorData.txt”. I don’t see how making an object and then making a copy of it calls any destructors at all… is this just a garbling of the wrong MATLAB output under each chunk of code?

2. Nick replied on :

I use destructors quite a lot. As clean up actions for temporary files. However, in the rare case that Matlab crashes (sic) the destructors are not executed. This way unwanted files are kept on the system. Do you see a solution for this?

3. Jennifer replied on :

Hi Sven,

Thank you for catching the problem of incorrect output in the original posting. It turns out that we made a mistake during the publishing process. There were extra variables in the workspace, which affected the output being generated. The posting has since been updated and the output is now consistent with the descriptions.

4. Jennifer replied on :

Hi Nick,
Thanks for sharing the ways that you use destructors. You raise a good point about what happens when MATLAB crashes. Unfortunately, when MATLAB crashes we don’t today have the ability to run destructors as MATLAB can’t reliably execute the destructor code after a crash.

5. Andrew replied on :

I like to keep in mind this sentence from the delete method documentation:

”A delete method should not generate errors or create new handles to the object being destroyed.”

@Nick: Do you mean the entire Matlab application or just your running code? if it’s the latter you might look into the always useful onCleanup.

Loren Shure works on design of the MATLAB language at MathWorks. She writes here about once a week on MATLAB programming and related topics.

These postings are the author's and don't necessarily represent the opinions of MathWorks.