(Script also on GitHub and MooTools Forge)

It’s great to track all of your classes’ instances for debugging purposes or mass altering.

Huh? Mass Altering?

  • For instances of some Audio/Video player classes: stop/pause all players
  • For instances of positioned elements: recalculate position of all elements upon window resize
  • Call hide method of all instances of a class upon an event

I needed it more than once and I used to track instances from within any class I needed it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var MyClass=new Class({
  initialize:function () {
      MyClass.instances.push(this);
  },
  recalcPosition:function () {
      // something that recalculates position or any other task that should happen on all instances
  }
});

MyClass.instances=[];

// from another code:
MyClass.instances.each(function (instance) {
  instance.recalcPosition();
});

However, I got too many classes with this behavior. I ended up writing a MooTools Class Mutator to automate the process:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
---

script: Class.Mutators.TrackInstances.js

description: Allows a class to track its instances by having instances array as a class property

license: MIT-style license

authors:
- Elad Ossadon ( http://devign.me | http://twitter.com/elado )

requires:
- core:1.2.4

provides: [Class.Mutators.TrackInstances]

...
*/

Class.Mutators.TrackInstances=function (allow) {
  if (!allow) return;

  // save current initialize method
  var oldInit=this.prototype.initialize;
  var klass=this;

  // overwrite initialize method
  klass.prototype.initialize=function () {
      (klass.instances=klass.instances || []).push(this);
      oldInit.apply(this,arguments);
  };
};

Usage:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var MyClass=new Class({
  initialize:function () {
  },

  TrackInstances:true,

  recalcPosition:function () {
      // something that recalculates position or any other task that should happen on all instances
  }
});

var x=new MyClass();
var y=new MyClass();

MyClass.instances; // [x, y]
MyClass.instances.length; // 2

// from another code:
window.addEvent("resize",function () {
  MyClass.instances.each(function (instance) {
      instance.recalcPosition();
  });
});

The only constraint is that the “initialize” declaration in an object should be prior to the TrackInstances:true. That’s because mutators are called in the same loop as all other methods, and if the loop didn’t get to a certain method, then the mutator won’t know it. According to these tickets, the MooTools team won’t fix it anytime soon.

Comments