Keyword methods

Most methods you’ll define using jsclass are listed explicitly in your source code. For example you might have a BlogPost class that has a publish() method, that you define by listing the method in the class body:

BlogPost = new Class({
    publish: function() { /* ... */ }
});

Keyword methods are different: they are methods that are generated on the fly and whose action depends on the context of the current method call. jsclass provides a few built-in keywords that you can use in any method you write.

callSuper()

This is used to invoke the current method in the next module up the inheritance stack. (See Inheritance for more information on how methods are looked up in jsclass.)

callSuper() automatically passes all the arguments to the current method up to the parent method, unless you override them.

Parent = new Class({
    say: function(something) {
        Console.puts(something);
    }
});

// Outputs "hello" 
new Parent().say('hello');

Child = new Class(Parent, {
    say: function(something) {
        // Outputs value of `something`
        this.callSuper();

        // Outputs uppercase version of `something`
        this.callSuper(something.toUpperCase());
    }
});

blockGiven()

Returns true if the current method was called with a callback function after the explicit arguments to the method.

Foo = new Class({
    say: function(a,b) {
        return this.blockGiven();
    }
});

var foo = new Foo();
foo.say('some', 'words') // -> false
foo.say('some', 'words', function() {}) // -> true

yieldWith()

If the current method was called with a callback function after its explicit arguments (as defined by blockGiven()) yieldWith() invokes the callback with the given arguments. If no callback was given, yieldWith() silently does nothing.

yieldWith() will use the argument after the callback (if one is given) as the this context for the callback.

Foo = new Class({
    say: function(a,b) {
        this.yieldWith(a + b);
    }
});

var foo = new Foo(), object = {};

foo.say('some', 'words', function(result) {
    // result == 'somewords'
    // this   == object
}, object);

Writing your own keywords

// In the browser
JS.require('JS.Method', function(Method) {... });

// In CommonJS
var Method = require('jsclass/src/core').Method;

You can use the same APIs that jsclass uses to create its built-in keywords to create your own. Remember, a keyword is a function that uses implicit contextual information from the current method call; if it looks like you can get the behaviour you want from a normal method, you should use one.

As a (very) simple example, let’s say we want a keyword method to return the number of arguments passed to the current method. Implementing this goes as follows.

Method.keyword('numArgs', function(method, env, receiver, args) {
    return function() {
        return args.length;
    };
});

This keyword is then available inside all your methods:

Foo = new Class({
    say: function(a,b) {
        return this.numArgs();
    }
});

var foo = new Foo();
foo.say('some')             // -> 1
foo.say('some', 'words')    // -> 2

Obviously this is a very basic example. The general pattern for using Method.keyword() is that you should provide a name for the keyword, and a generator function for it. This function should accept the following arguments and return another function that implements the keyword:

Using this contextual information you can generate functions that do all sorts of useful things with the current method call. As a more complex example, here is the jsclass implementation of callSuper:

JS.Method.keyword('callSuper', function(method, env, receiver, args) {
    var methods    = env.lookup(method.name),
        stackIndex = methods.length - 1,
        params     = Array.prototype.slice.call(args);

    return function() {
        var i = arguments.length;
        while (i--) params[i] = arguments[i];

        stackIndex -= 1;
        var returnValue = methods[stackIndex].apply(receiver, params);
        stackIndex += 1;

        return returnValue;
    };
});