MooTools setOptions() nullifies object references

I bumped up into a problem where the object references where resolved as object copies when I passed them to class instances. That might sound easy to resolve, but unfortunately I was already deep in code and it was difficult to see this. Therefore, here’s a little explanation for those who are facing the same frustrating issue.

Say, you have variable ‘a’ and you want to pass it to a MooTools class B instance during creation. In the easiest case you’d use new B({ myReference: a}) and trust on MooTools’ Class.setOptions() to minify the need of code lines. This is what you should do… well at least that’s what I did and in this case it was a mistake.

It turns out that Class.setOptions() merges it’s arguments to this.options and then takes copy of them via $merge(). That means that any variable references you pass to setOptions() will get copied to this.options and.. well, that’s it. See lines 1170-1173 in uncompressed version of MooTools 1.2:

var Options = new Class({
    setOptions: function(){
        this.options = $merge.run([this.options].extend(arguments));

That effectively nullifies the benefits of Class.setOptions() if you want to pass in variable references..

Here’s a longer example to clarify (use Firebug):

  // The most basic MooTools class that implements options
  // ref is a variable meant for pointing at given object
  // (won't do that, however)
  var B = new Class({
    Implements: Options,
    options: {
      ref: null
    },
    initialize: function(options) {
      this.setOptions(options);
    }
  });

  // Ok let's create an instance that we can pass to B
  // It's similar with all sorts of variables
  var A = new Class({
    initialize: function() {
      this.somevar = 'untouched';
    }
  });
  var a = new A();
  
  // Create an instance of B and give it somevar as reference
  var b = new B({ ref: a });

  // prints out "untouched" as should
  console.log(b.options.ref.somevar);

  // Let's change the variable (direct access, bad)
  a.somevar = "changed";

  // b's reference should still point to a, right?
  // In that case the following should print "changed",
  // but because our reference object was copied instead
  // of retaining reference to it, we just get "untouched"
  console.log(b.options.ref.somevar);

I don’t know why MooTools wants to make a copy of arguments in setOptions() – propably for performance reasons.

2 thoughts on “MooTools setOptions() nullifies object references

  1. this was just driving me insane! Have you come across with any creative solutions for working around this?

Leave a Reply

Your email address will not be published. Required fields are marked *