Out of Hanwell

March 29, 2006

JavaScript range Function

Filed under: Uncategorized — Matthias Miller @ 12:33 pm

Sometimes I get hit by random thoughts in the middle of some programming changes. Have you ever wanted to write code like this?

for (var i in range(12)) ...

or:

for (var i in range(-10,11,5)) ...

More likely than not, somebody else has already tried this, but I couldn’t find any implementations. Just to prove that it’s possible–and with no regard to efficiency–here’s the magic function:

function range(/*[start,] stop[, step]*/) {
if (!arguments.length) {
return [];
}

var min, max, step;
if (arguments.length == 1) {
min = 0;
max = arguments[0]-1;
step = 1;
}
else {
/* default step to 1 if it's zero or undefined */
min = arguments[0];
max = arguments[1]-1;
step = arguments[2] || 1;
}

/* convert negative steps to positive and reverse min/max */
if (step < 0 && min >= max) {
step *= -1;

var tmp = min;
min = max;
max = tmp;

min += ((max-min) % step);
}

var a = [];
for (var i = min; i <= max; i += step) {
a[i] = i;
}
return a;
}

Done. Back to work.

Update: I forgot to mention that negative steps return the correct values, but in the wrong order. Also, MochiKit provides a range function but the results can only be iterated with library functions and cannot be iterated with the for keyword.

Advertisements

March 27, 2006

JavaScript Inheritance

Filed under: Uncategorized — Matthias Miller @ 8:14 am

When I first starting developing in JavaScript, I thought inheritance to be practically mandatory for clean, object-oriented design. In C++, for example, inheritance is necessary to provide interfaces, to allow the use of objects that are basically the same but to provide agnosticism about the ways those objects diverge. Although I still believe JavaScript inheritance can be a useful tool, I’ve concluded that it’s far less critical than I thought.

Inheritance is unfortunately messy in JavaScript. Inheriting one class from another requires two things. First, prototype of the base class must be set to an instance of the parent class, which gets particularly unfriendly when the parent class expects to receive arguments in its constructor. Second, the constructor of the base class must call the constructor of the parent class. But even after those problems are solved, it is difficult to call a function in the base class after it has been overridden in the derived class. The awkward syntax for inheritance leaves something to be desired.

Fortunately, these problems can be solved by writing helper code to take away the ugliness. On Thursday Dean Edwards showed a superb example of a base class for JavaScript inheritance, providing an easy way to extend objects and override functions. If you’re wanting inheritance in JavaScript, this is the way to go.

Let me caveat that that I would rather develop a comprehensible framework with many small tools at my disposal than use a framework that abstracts all imaginable details. To that cause, if there are limitations in the JavaScript language, I am more likely to find simpler constructs that are native to the language than to build my own constructs on top of the language, especially when it means making nearly all my source files dependent on that abstraction.

Here are some simple constructs that can replace the unnatural constructs for derived classes:

  • Contracts can replace interfaces. Imagine the simple abstraction of a stream that can be file-based or memory-based. In C++, this might be implemented as a base CStream class, with derived CFileStream and CMemoryStream classes. An XML parser, for example, might receive a CStream pointer with which it can seek, read, and write. In JavaScript, however, these interfaces can be defined by a contract. An XML parser could require a reference to an object with seek, read, and write member functions.

  • Shared objects can replace virtual functions to facilitate code reuse. Instead of deriving the Salesman and Programmer classes from a Person class, they might simply contain a reference to a VitalStatistics object.

  • Callbacks can replace virtual functions to facilitate branching of code. Function callbacks are much easier in JavaScript than in C++. Consider a function that takes a regular expression and replaces each instance with a caller-generated response. (For example, the caller may want to find all numbers and replace them with their square.)

    In C++ you might create a class with a single Replace function, accepting a regular expression. The Replace function would invoke a virtual function to determine how to replace the occurances of the regular expression. Alternatively, you might break this class into two functions: one that finds all instances of a regular expression and one that replaces substrings with strings from a parallel array.

    In JavaScript the use of a callback is trivial, making it a likely candidate for this kind of code branching.

Don’t use these techniques unquestioningly. Build something that simple and maintainable. And if you must, use inheritance.

March 23, 2006

Even Better Object-Oriented Callbacks

Filed under: JavaScript — Matthias Miller @ 7:33 pm

I recently described a function that I use to bind a callback’s this with a specific object. However, this evening I was fighting a limitation with that function. When I’m creating a callback, I sometimes want to specify parameters immediately and sometimes want to defer them until it is called.

I’ve changed the function to look like this:

function createObjectCallback(obj, fn, argumentsOverride)
{
return function() { fn.apply(obj, argumentsOverride || arguments); };
}

I can now do this:

var fn = createObjectCallback(logger, showMessage);
fn(“Hello World”);

Or I can do this:

var fn = createObjectCallback(logger, showMessage, [“Hello World”]);
fn();

March 21, 2006

Crime and Punishment

Filed under: Uncategorized — Matthias Miller @ 10:03 pm

Every programmer needs to get his head out of computers. Over the past week I read Crime and Punishment for the first time. Without wasting words over such a widely-reviewed book, here are some observations:

  • This book really drew me into the experience of the characters; that I was so strongly peeved by certain characters is good evidence.
  • The tension (especially inner conflict of Rodya), suspense, and various graphic details make it easy to pick up and difficult to put down.
  • Though the book should not be read solely for its philosophy, its philosophical aspect is nevertheless interesting.
  • It’s an easy read.

It’s an excellent book. I stayed up way too late reading it.

March 18, 2006

Primitive Programming

Filed under: Uncategorized — Matthias Miller @ 5:45 pm

I suppose this is what programming was like back in the days when cavemen scratched their programs onto the walls of a cave. I am glad somebody thought of inventing booleans, numbers, classes, and objects.

Clever.

March 16, 2006

Blog Spam Filtering

Filed under: Uncategorized — Matthias Miller @ 7:54 am

Akismet rocks!

I’ve been getting fed up with blog spam the last several weeks. For the most part, I’ve been able to blacklist keywords and keep going. But this morning, I woke up to over a hundred spam comments on my blog. Even worse, the b2evolution spam filtering didn’t stop them from coming through. Enough!

As much as I hate to do this (knowing that it’s going to cost me when I try upgrading my blog), I’ve cobbled together some b2evolution integration with Akismet. You must sign up for a WordPress account to use it, but that’s pretty painless. I used the well-written PHP interface developed by Alex Potsides, although I had to make a number of changes to get it to run on PHP4.

If Akismet reports a comment as spam, the comment is stored with a special “spam” comment type and the e-mail notification contains a bold “**SPAM**” in the subject. If an item is incorrectly flagged as spam, I can use the MySQL client or online administrator to turn it into a real comment.

Is this the right solution? Hardly. It’s ugly. It’s costly to set up, administer, and maintain. b2evolution really needs native Akismet support.

But it works. Spammers are having a much tougher time desecrating my blog, and I’m much happier now.

Way to go, Akismet!

March 13, 2006

JSONRequest Proposal

Filed under: Uncategorized — Matthias Miller @ 9:41 am

Although the idea is (generally) a good one, I have some suggestions for improvement of Douglas Crockford’s recent proposal for an XMLHttpRequest equivalent for JSON.

  • The overloads for the JSONRequest function are confusing, and the parameter names could be clarified. Instead of overloading, it would make more sense for JSONRequest to be an object and to have two functions: JSONRequest.send(url, object, callback, timeout) and JSONRequest.cancel(requestID).

  • JSONRequest may be used for two situations: accessing exposed web services and accessing site-specific services (a typical Ajax scenario). Exposed web services will typically be provided by a third party, while site-specific services will always be served by the site’s host. Because many JSON requests only make sense in the context of an already-authenticated session, such site-specific requests should be allowed the use of cookies. This would allow reuse of existing cookie-based authentication architecture.

There have been some interesting comments about this over on Ajaxian this weekend.

March 10, 2006

Object-Oriented Callbacks

Filed under: JavaScript — Matthias Miller @ 3:29 am

In my last post, I discussed how object-oriented JavaScript code should be written. But there’s sometime important that I didn’t mention.

What about callbacks? Remember that the value of this is determined when the function is called, not when it is defined. This means the following code (using the previous post’s example) will blow up:

var o = new Container();
var fn = o.service;
fn();

I’ve created a simple utility function that makes callbacks easier, not only with my own objects, but also with DOM objects. Simply put, this function allows you to specify what the value of this should be when your callback is called.

function createObjectCallback(obj, fn)
{
return function() { fn.apply(obj, arguments); };
}

The previous example can be rewritten like this so that it does not blow up:

var o = new Container();
var fn = createObjectCallback(o, o.service);
fn();

You can use this function when you’re setting up timers:

function MyTimedObject(interval)
{
this._value = 0;
window.setInterval(createObjectCallback(this, this._doAction), interval);
}

MyTimedObject.prototype._doAction = function()
{
/* do something! */
this._value++;
};

/* use MyTimedObject */

And if you’re using Ajax, you can use this function to create your onreadystatechange handler, with this set to the appropriate XMLHttpRequest object.

function onReadyStateChange()
{
/* do something if (this.readyState == 4) */
}

var oXHR = new XMLHttpRequest();
oXHR.onreadystatechange = createObjectCallback(oXHR, onReadyStateChange);
oXHR.open(“GET”, /*URL*/, true);
oXHR.send(“”);

It’s amazing how often such a little function can be used.

March 8, 2006

Object-Oriented JavaScript

Filed under: JavaScript — Matthias Miller @ 4:58 am

Several months ago I complained about the limitations of object-oriented JavaScript. I’ve changed my mind.

Douglas Crockford advocates using closures to provide private members, and that’s what I had been doing. Here’s an example from his website:

function Container(param) {

function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}

this.member = param;
var secret = 3;
var self = this;

this.service = function () {
if (dec()) {
return self.member;
} else {
return null;
}
};
}

I tried this for quite a while. It worked for simple objects, but it didn’t scale. It was very difficult to keep track of all the variables. I kept asking myself, “Is this variable a parameter to the constructor, a parameter to a function, or a private member?” I kept tripping up with the this keyword, which Crockford works around by using a “self” variable. Why can’t I use the keyword that’s built into the language?

I’ve found it more natural to prefix the names of private members with an underscore. This allowed me to write much simpler, cleaner, and easier-to-maintain code. Private members simply become a contract with the caller–do not use any properties prefixed with an underscore!

Crockford’s example could be rewritten like this:

function Container(param) {
this._secret = 3;
this.member = param;
}

Container.prototype._dec = function() {
if (this._secret > 0) {
this._secret -= 1;
return true;
} else {
return false;
}
};

Container.prototype.service = function () {
if (this._dec()) {
return self.member;
} else {
return null;
}
};

This code eliminates one level of nesting, making it easier to read. It is obvious which variables are parameters and which are members, and which members are public and which are private. This code does not need to reference the redundant “self” variable because each function can assume that this is a reference to a Container object.

Object-oriented JavaScript doesn’t have to be the nightmare that I thought it was.

March 6, 2006

Creating the XMLHttpRequest Object

Filed under: Uncategorized — Matthias Miller @ 8:16 am

I suppose there are a million ways of doing this, but here’s one I think makes more sense than nested try/catch statements (adapted from ADC’s example). It’s certainly more readable.

function createXHR()
{
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest) {
try {
return new XMLHttpRequest();
} catch(e) {
}
}

// branch for IE/Windows ActiveX version
if (window.ActiveXObject) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
}

try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
}
}

return null;
}

(But do you really care?)

Blog at WordPress.com.