Recent Changes - Search:

edit SideBar

Extend

An accessor may specify that it extends another accessor in its setup() function by invoking:

  • extend(<string> name): Extend an accessor with the specified name.

This has the effect of implementing the interface of the other accessor, as if implement had been invoked, but in addition, it inherits all exported fields and functions of the specified accessor.

For example, suppose a base accessor MyBase has the following:

  exports.initialize = function() {
    console.log('Initialize base accessor.');
  }

Then if an accessor specifies the following:

  exports.setup = function() {
    extend("MyBase");
  }

then it will inherit the initialize() function of the base accessor.

An accessor may override any exported function of the base accessor by simply defining a function with the same name. Moreover, the override function can invoke the overridden function as in the following example:

  exports.initialize = function() {
    this.ssuper.initialize();
    console.log('Initialize extended accessor.');
  };

When the initialize() function of the extended accessor is invoked, then the following will appear on the console:

  Initialize base accessor.
  Initialize extended accessor.

An accessor can also override input handler functions. Suppose that a Base accessor has the following:

exports.inputHandler = function() {
   // Send true to output.
   send('output', true);
}
exports.initialize = function() {
   addInputHandler('input', this.inputHandler);
}

Then a Derived accessor that extends this base can override the input handler with the following code:

exports.inputHandler = function() {
   // Send false to output instead.
   send('output', false);
}

exports.initialize = function() {
   this.ssuper.initialize.apply(this);
}

In an instance of Derived, when an input arrives on 'input', the accessor will send false to 'output', not true as in the Base accessor. Notice particularly the line in Base above:

   addInputHandler('input', this.inputHandler);

The use of the keyword this is important here. Here, this.inputHandler refers to the 'inputHandler' property of the object on which initialize() is invoked, which will be the Derived accessor. This is because the Derived accessor binds the 'this' value to its own exports object when calling Base.initialize(). Hence, this.inputHandler refers to the overriding function. If instead we had written in the base accessor

   addInputHandler('input', exports.inputHandler);

then the override would not succeed. Here, exports.inputHandler is resolved in the scope in which initialize() is _defined_, not in the scope in which it _executes_. Therefore, exports.inputHandler refers to the 'inputHandler' property of the Base accessor. This latter pattern can be used to prevent extended accessors from overriding certain behavior.

A derived accessor may modify the options of the inputs, outputs, and parameters of the extended accessor. For example, if ```MyBase``` has a parameter named 'foo', then

  exports.setup = function() {
    extend('MyBase');
    parameter('foo', {'value':43});
  }

modifies the default value of 'foo' from whatever it is in the base to 43.

See Support for implement and extend in Ptolemy II.


Back to accessor specification

Edit - History - Print - Recent Changes - Search
Page last modified on January 07, 2016, at 07:06 PM