Destroying an instance of a Matlab Singleton class without calling `clear all`

According to Matlab documentation , to create a Singleton design pattern you need to set a variable persistent

inside a static function for your singleton object e.g.

classdef (Sealed) SingleInstance < handle
  methods (Access = private)
    function obj = SingleInstance
    end
  end
  methods (Static)
    function singleObj = getInstance
      persistent localObj
      if isempty(localObj) || ~isvalid(localObj)
        localObj = SingleInstance;
      end
      singleObj = localObj;
    end
  end
end

      

It is almost impossible to "destroy" a singleton instance. I tried to clear SingleInstance

, clear getInstance()

, clear SingleInstance.getInstance()

, clear functions

, clear variables

and other combinations. The only way for a constant variable localObj

in a static getInstance()

class method SingleInstance

is to call clear all

.

I'm fine with a call clear all

before calling my Matlab OO application. However, I am using the Matlab unit test framework and there are unit tests where I would like to test different ways of instantiating singleton classes. However, for this I will need to call clear all

, which will cause the Matlab unit test framework to stop working.

Does anyone know a way to clear a constant variable inside static methods of Matlab classes without calling clear all

? Or else, does anyone know how to implement the Singleton design pattern without using variables persitent

? Or at least as a call clear all

inside unit tests without breaking the unit test infrastructure?

+3


source to share


2 answers


You should use delete

or see Doc

clear

You can also look in the family clear classes

, but that won't work for you as it does the same thing clear all

and also removes the class definition.

You have nothing to change in the construct of the singleton type class to destroy the instance of the object handle

you should be using delete object2dispose

. When you use clear object2dispose

, you only clear the variable on the stage that contains the handle to your object, but you do not destroy the object itself. This is why when you call the method getInstance

, you still see that the descriptor is stored in a constant variable localObj

(which is one of the purposes of storing the descriptor you saved).

So if I use

sobj = SingleInstance.getInstance %// instantiate object
clear sobj                          %// clear it ? (... not really)

sobj = SingleInstance.getInstance %// To see the state of "localObj"

      

I stopped in the debugger while executing the third line and I get: instantiated

My variable sobj

disappeared from the workspace when I called clarity, but the object still existed in memory (and the handle is still being saved to the variable localObj

).

If now replace the second line with



delete(sobj)

      

In the workspace, you get:

>> sobj
sobj = 
  handle to deleted SingleInstance

      

And on the next call getInstance

in the debugger, I get: deleted

localObj

that appear on the Stage still appear as a handle SingleInstance

, but it knows that the object has been deleted.

So, in the design of your class, you can check the state localObj

before proceeding with it.

the function isvalid

is useful to know if the handle is pointing to a real object or not.

+2


source


My first thought is that you should avoid single and other forms of global state whenever possible, not only for validation, but also for cleanliness and interface integrity. More details here and here .

Another thought is that you can issue the following call:

classdef FuadTest < matlab.unittest.TestCase

    methods(Test)
        function testSomething(testCase)
             clearClasses;
             % Do other stuff
        end
    end
end

function clearClasses
clear classes;
end

      

This is where you need to put the call to clear classes in your own local function (or private method, static method, etc.) so that you understand the clarity in your scope and don't clear all other variables in yours (for example testCase

). If in your own function you don't need any other variables in this scope so that you can clean up the classes efficiently.



A word of warning, however, using clear classes in this way is really a scent trying to tell you something (primarily to avoid global state) and you should expect to run into idiosyncrasies. For example, I believe that calling clear classes cleans up the profiler data, so you won't be able to effectively measure your code coverage using the CodeCoveragePlugin .

Hoki's answer is fine as long as you are fine with the ability for the user to clear one and only instance, which can also clear the global state that your application depends on and can cause errors in the future if you're not careful.

Hope it helps!

0


source







All Articles