A simple(r) approach for class-based OOP in JavaScript

Filed under: Dynamic scripting, Research, Techniques and algorithms

Like others before me, I found JavaScript’s prototype-based OOP support – while very powerful – quite cumbersome in some situations where I needed a certain structure or hierarchy of objects, situations in which one quickly comes to the conclusion that the best answer would be the concept of a Class.

However, while I am well aware that the web is filled with various implementations of classical (i.e. class-based) object orientation in JavaScript, I can not help the feeling that they are over-engineered and over-complicated without need, quite often attempting to provide more functionality than is actually necessary. In short, I don’t feel they’re “classical” at all.

This is why I started working on my own implementation of classical OOP  in JavaScript, which is shown below. Currently this is only a proposal, although I already started using it in one of my projects. Anyway, let’s look at it first then I’ll try and explain how it works.

The Code

/** Class factory. */
function Class(members) {

    // proxy constructor
    var Proxy = function() {
        for (var item in members) {
            this[item] = members[item];
        }
    };

    // proxy inheritance
    Proxy.prototype = (members.base || Class).prototype;

    // class constructor
    var Build = members.init || function() {};

    // class inheritance
    Build.prototype = new Proxy();
    Build.prototype.base = Proxy.prototype;
    Build.prototype.constructor = Build;

    // ready
    return Build;
}

That is all, and this little function can have a whole world of nifty consequences like deep inheritance or access to the super-class via this.base (and others). But here is what happens: the basic principle at work here is the Proxy object, which essentially, contains all the members of our new class (the ones that are passed to the Class factory function as the members parameter). Read the rest of this entry »

Posted on June 18th, 2011 by Valeriu Paloş

1 Comment »

Case study: fixed number of iterations with LPeg

Filed under: Dynamic scripting, Research

Words seem to fail to describe just how awesome LPeg is. Designed as a Lua implementation of the PEG concept, it is a true programming gem! Please, if you dont’t know what it is, take some time to familiarize yourself with it! It’s not the easiest thing to grasp, but you will not regret it! It is certainly one of the most worthwhile learning efforts you can make in generic parsing.

One great feature of LPeg is that it’s binary-safe, meaning that (unlike regular expressions) it can be safely used to parse binary data! This makes it an excellent tool for parsing binary protocols, especially network communication protocols, such as the Action Message Format (used by Adobe Flash for making remote calls and even in FLV movie files). I’ll leave it to you to explore the possibilities…

Beware that from here on, I assume that you know your way around Lua, LPeg and how they work.

The problem

That being said, this article is actually about an unusual roadblock I hit while using LPeg to build a Lua-based AMF parser, and the various solutions I found and/or came up with to overcome it (you didn’t think that I mentioned AMF before by accident, did you?).

The issue is LPeg’s implementation of repetitive patterns: in particular, its inability to match (or capture) a fixed number of occurrences of a certain pattern, although it can match a minimum or a maximum number of such occurrences, which is perfect for stream-oriented parsing (such as parsing programming languages) but insufficient for binary data.

Just to clarify, here’s a small list of LPeg patterns which correspond to the typical PCRE repetitive constructs (in each case we’re trying to match the string ‘cloth’):

Matching occurrences of ‘cloth’ PCRE pattern LPeg pattern
0 or more (at least 0) /(cloth)*/ lpeg.P'cloth'^0
1 or more (at least 1) /(cloth)+/ lpeg.P'cloth'^1
X or more (at least X) /(cloth){X,}/ lpeg.P'cloth'^X
1 or less (at most 1) /(cloth)?/ lpeg.P'cloth'^-1
X or less (at most X) /(cloth){,X}/ lpeg.P'cloth'^-X
A: precisely X (no more, no less) /(cloth){X,X}/ -- unavailable --
B: anywhere between X and Y /(cloth){X,Y}/ -- unavailable --

For the last two cases (i.e. A and B), LPeg does not offer any simple constructs so we have to find a complex one. Let’s put aside the case B for now, and try to tackle A… Read the rest of this entry »

Posted on September 1st, 2010 by Valeriu Paloş

No Comments »

Copyright ©2012 Valeriu Paloş. All rights reserved. Design based on a template from Hive Designs ported by Theme Lab.