CrxOop CrxOop: Bringing Object Oriented Programming, and Proper Prototype Based Programming, To Javascript
The aim of the library documented below is to provide developers with a solution to allow development using interfaces and classes as they are known in other object oriented programming (OOP) languages such as C++, C#, Java and PHP. Further more, V1.4 introduces structures, a generalization of the concept of prototypal inheritance, known here as POBP.
Subject
Body*
Email
SUBMIT CLOSE
Menu

3.6.8 ANNUL

ANNUL is a function. For various reasons CrxOop does not give an implementation for destructors. After contemplating many ideas, ANNUL was invented. ANNUL should allow developers to provide their own destructor mechanisms should they need to.

If this.ANNUL() is called, the object pointed to by 'this' is locked. Any further access to the object members will lead to fatal errors. 'ANNUL' must never be passed to functions as parameters or from functions as returns. Misuse of this keyword can also lead to fatal errors.

crxOop.isAnnul() can be used to check whether an object has been annuled.

The following is an example of how a destructor mechanism could be implemented using ANNUL.

JS (Tree)
(function()
{
   var instances = {};
   var id = 1;

   //   A base class for all our classes that follow the destructable class pattern.
   crx_registerClass('Base',
   {
      PRIVATE:
      {
         VARS:
         {
            'id': 0
         }
      },
      PUBLIC:
      {
         CONSTRUCT: function()
         {
            //    Saving a reference of the instance into our private
            //      local closure. Why one might need to do this
            //      is beside the point. Assuming you do need to
            //      do this, you need to worry about freeing the
            //      memory when the object is no longer
            //      needed. Look at our 'destruct' function below.
            this.id = id;
            instances[id] = this.THIS;

            id = id + 1;
         },
         VIRTUAL:
         {
            FUNCTIONS:
            {
               //   Our destructor function.
               'destruct': function()
               {
                  //   The following will not delete the instance.
                  //      There might be other references   to it
                  //      elsewhere.
                  delete instances[this.id];
                  
                  // The following will also not delete the instance.
                  //      However, now the instance is roughly as good
                  //      as deleted. Any use of this instance later
                  //      on will cause fatal errors. This will allow
                  //      developers to see these errors before their
                  //      code is released.
                  this.ANNUL();
               }
            }
         }
      }
   });
})();

crx_registerClass('SomeClass',
{
   EXTENDS: 'Base',
   PRIVATE:
   {
      VARS:
      {
         'someString': null
      }
   },
   PUBLIC:
   {
      FUNCTIONS:
      {
         'setString': function(pString)
         {
            this.someString = pString;
         },
         'doSomething': function()
         {
            console.log(this.someString);
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            //   Our destructor function.
            'destruct': function()
            {
               //   Freeing our resource
               this.someString = null;

               //   Allowing upper classes to free their resources.
               //      Notice how we do not call 'ANNUL' here.
               //      This is because 'ANNUL' must be called as the
               //      last line to avoid errors from further access
               //      to the object. This means, the last line in
               //      the last destruct function to be called,
               //      which is Base::destruct()
               this.SR(null, 'destruct');
            }
         }
      }
   }
   
});

var a = crx_new('SomeClass');

a.setString('Some very large resource');
a.doSomething();

//   We are now done.
a.destruct();

//   The following will cause a fatal error.
//a.doSomething()

//   The following will not. 'crxOop.isAnnul' can be used to check if the object has been
//         annuled, which in our case is true.
if(!crxOop.isAnnul(a))
{
   a.doSomething();
}
JS (Verbose)
(function()
{
   var instances = {};
   var id = 1;

   //   A base class for all our classes that follow the destructable class pattern.
   crx_registerClass('Base',
   {
      'VERBOSE': 1,
      'private var id': 0,
      'public CONSTRUCT': function()
      {
         //    Saving a reference of the instance into our private
         //      local closure. Why one might need to do this
         //      is beside the point. Assuming you do need to
         //      do this, you need to worry about freeing the
         //      memory when the object is no longer
         //      needed. Look at our 'destruct' function below.
         this.id = id;
         instances[id] = this.THIS;

         id = id + 1;
      },
      //   Our destructor function.
      'public virtual function destruct': function()
      {
         //   The following will not delete the instance.
         //      There might be other references   to it
         //      elsewhere.
         delete instances[this.id];

         // The following will also not delete the instance.
         //      However, now the instance is roughly as good
         //      as deleted. Any use of this instance later
         //      on will cause fatal errors. This will allow
         //      developers to see these errors before their
         //      code is released.
         this.ANNUL();
      }
   });
})();

crx_registerClass('SomeClass',
{
   'VERBOSE': 1,
   'extends': 'Base',
   'private var someString': null
   'public function setString': function(pString)
   {
      this.someString = pString;
   },
   'public function doSomething': function()
   {
      console.log(this.someString);
   },
   //   Our destructor function.
   'public virtual function destruct': function()
   {
      //   Freeing our resource
      this.someString = null;

      //   Allowing upper classes to free their resources.
      //      Notice how we do not call 'ANNUL' here.
      //      This is because 'ANNUL' must be called as the
      //      last line to avoid errors from further access
      //      to the object. This means, the last line in
      //      the last destruct function to be called,
      //      which is Base::destruct
      this.SR(null, 'destruct');
   }
   
});

var a = crx_new('SomeClass');

a.setString('Some very large resource');
a.doSomething();

//   We are now done.
a.destruct();

//   The following will cause a fatal error.
//a.doSomething()

//   The following will not. 'crxOop.isAnnul' can be used
//      to check if the object has been annuled, which
//      in our case is true.
if(!crxOop.isAnnul(a))
{
   a.doSomething();
}