Archive for October, 2012

7Oct

Lately I’ve been working on a client/server side validation library. I had a need to chain a bunch of methods together, and what that meant was a need to modify how the original functions were called without changing them. This lead to a need to pass some variables into a function and still wait to accept more parameters later. I already knew about currying, which I will summarize as being able to pass as many variables as you feel into a function. A couple other techniques were needed to solve this.

First I learned about the apply and call functions (I know I am late to the party…). In this case apply was extremely helpful, it let me set a context (change the value of this) and collect some parameters together and pass them into a function.

Next I discovered partial applications. This is more of a technique than anything else. In iz we have the following source code:

function validator_partial(fn) {
    //get all arguments except the first, which is the function name
    var args = Array.prototype.slice.call(arguments, 1);
    //pass the "value" in as the first parameter so that the user of this library doesn't need to
    args.unshift(value);
    //return a new function
    return function() {
        //combine all arguments made to this function with the ones above
        var allArguments = args.concat(Array.prototype.slice.call(arguments)),
        //get the result
        result = validators[fn].apply(null, allArguments);
        //update this object
        if (!result) {
            if (typeof this.error_messages[fn] !== "undefined") {
                this.errors.push(this.error_messages[fn]);
            } else {
                this.errors.push(fn);
            }
            this.errors.push(fn);
            this.valid = false;
        }
        //return "this" to allow for chaining of methods
        return this;
   };
}

for (var fn in validators) {
    //for each function, call the partial and pass in the function
    if (validators.hasOwnProperty(fn)) {
        Iz.prototype[fn] = validator_partial(fn);
    }
}

At the bottom I am grabbing the validators, and assigning them to the prototype of the Iz object. Before the validators get called though they go through a partial. This partial is a function that returns a function. The closure allows you to house some variables within it. When the returned function gets called it has access to the outer one’s scope, which is how you are able to pass in parameters before and after the function is called. On top of that this system lets you pass in as many params as you need and it simply forwards everything on.

With this method I was able to replace all of the first parameters (the ‘values’ with the value from the Iz object. This means less typing, which is always nice!

Share/Save