Saturday, 29 August 2009

Code-writing code in Javascript ;

When you are coding in Lisp it is perfectly natural to write code that writes code. You make your own language as you go. This is with Lisp macros. I have explained macros in Javascript in another post. You actually can use a similar technique in Javascript, but without macros.

One thing which is very use for code-writing code is to implement a specification of some kind. It can be many kinds of specifications, in this example the spec is a CSV file. That is a comma separated file. You have a list of headers meaning something, and you want to make a program to read this file and access the different rows and columns.

Imagine the specification defines customerNr, hairColorId, and so on, in total maybe 53 fields. You want to access these properties in different ways and have some nice solution to keep it all together. Perhaps you want an event system, so other objects can listen to when the hairColorId changes and update something on the screen.

If you are a certain kind of consultant you will want to store the 53 fields in an array and remember the index number of each property. Now if someone inserts a changes the spec you will have to spend a lot of time updating the index numbers. Also it will make it very unreadable, what does theArray[11] really mean? If you are lucky you are the only one that knows and you will be irreplaceable.

I don't want to store it as a JSON type object literal. If we use direct access it makes it difficult to add the event feature, checking the validity of the data and things like this. Access should be through functions.

I don't want the upcoming javascript magic set/get handing of properties. It hides the fact that access is made through a function and makes it difficult to find things that need to be refactored. You can't tell if someclass.customerId is direct access like in the previous section (refactor in my opinion) or a magic setter. The ugly smell has gone, and we need the smell to be able to refactor.

I would want to access this with read/write set/get och what ever you call them, accessor functions. They are a nice spot to throw out events and makes it easy to change the specification. But I don't want to make all these getter and setter functions manually. It makes it error prone and quite difficult to update. And I definitely don't want some magic XML spec outside the file generate the code for me. I want to have control.

I want something like this:

var specification = ['customerId','hairColorId'];
var customer = makeCSVwrapper(specification);
customer.onHairColorIdChange(function () {
alert("Changed hair: " + customer.getHairColorId());
var csv=customer.formatCSV();

What is the deal?

The whole specification is defined in one line of code. set- and get- functions are created automatically based on the spec.

If a new field is added to the specification we only need to update in one line of code. No editing of setters and getters.

If hairColorId is removed from the specification, we only need to change in one line. And we will spot deprecated code because customer.setHairColorId will now be an error. But if we had direct access as customer.hairColorId = 'blue' this would not cause an error. It would be a bug more difficult to detect.

The risk of typing errors in your setters and getters decrease. The file size decrease. Finally it shows something Javascript can do but most languages can't.


I have a flashy alert-message based demo and source code you can try.

No comments:

Post a Comment