When I first started to work with web applications, it was just servlets and then came JSPs. At the time, I didn't like JSPs (and to this day I still don't). They seemed like a necessary evil that got the job done. The thing I found repulsive about them was the mix of server and client code together. The switching of contexts just made both look ugly and hard to maintain. But, it was easier than generating pages directly from servlets by hand. Of course, there were other solutions that I looked for, but nothing got away from the horrid markup. Then, I fell in love with Seaside which did away with markup and generated content through a custom DSL. It felt better to me and loved it until I realized that it was only for the developer, not the web page designer. It made their life harder. Now, we all know we should use minimal content and have CSS do the layout. But, in this modern world, you need folks who are experts at web page design. You can not and should not alienate them.
Fast forward to now. Currently, I've been using Javascript frameworks and working mainly from the front-end. The project I'm currently working on is pure HTML/Javascript/CSS for the front-end with RESTful calls to the backend. I must admit, I had my reservations about this arrangement, but after working with it; it is the right thing to do. No more ugly markup. The separation of concerns is well in place. And finally, the web designer is allowed to concentrate on making a rich user experience and the developer to concentrate on business logic. Perfect.
My feeling is that the days of template engines are over. It's a waste of time and all of them are a pain to debug. A pure Web 2.0 AJAX solution allows each to utilize their tools and do things separately. To me that is exciting and I will gladly leave ugly code behind.
Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts
Saturday, June 04, 2011
Friday, March 11, 2011
Singleton Pattern in Dojo
Recently, I needed to have a singleton object. So, I came up with the following implementation to give me just that.
When declaring my class in Dojo, I did the following:
var makeSingleton = function (aClass) {
aClass.singleton = function () {
var localScope = arguments.callee;
localScope.instance = localScope.instance || new aClass();
return localScope.instance;
};
return aClass;
};
When declaring my class in Dojo, I did the following:
makeSingleton(dojo.declare(...));Then, to use it:
var instance = myClass.singleton();I like the fact with this implementation that it's obvious that I'm creating a singleton object up front around the dojo.declare. Of course, there's nothing preventing someone from creating the class with new, but we could easily get around that with throwing an exception in our constructor after our singleton has been initialized.
Tuesday, May 13, 2008
Javascript: Stop Fighting It
I recently came to the realization that I've been fighting Javascript too much. It's because I've been going against the grain with it. It's like trying to force the OO paradigm in a functional language or the opposite. You might say that I've been treating Javascript like an OO language and you would be right. But, I've been forcing my class-based thinking on it and it's been not so nice.
I've been reacquainting myself with Self and Io again. And it hit me like a rhino slamming into me. I've been doing Javascript all wrong. I should have treating it like the prototype-based language that it is. Sure, it doesn't have the ability to inherit from multiple prototypes like Self, but the way to succeed is with prototypes. Forcing class-based OO is like walking up the rainbow and finding no pot of gold at the end.
First, let's write the following:
It's just two methods up on the Object prototype. Why clone is not part of the Javascript standard is beyond me. Clone is required in all the other prototype-bases languages I have seen. It is the only way to create new objects. Enough complaining, it was only a few lines of code. All my clone method does is make the object I call it on the prototype of the result. I get a clean object with all of the properties of the receiver inherited. Nice. This is the behavior we want. Next, I added a convenience method to Object to mix-in in other objects. This is helpful to keep my code organized. I can just create a hash object with my functions and properties like before. So far, this is standard stuff. But, here is how I use it:
Notice, normally, you define the constructor with the first letter of the name upper cased. I no longer need the constructor, so I upper case on the prototype that will be the example for all the instances that I clone off it. The example above is a measurement class. "Pounds" is my example so I default it with values that the objects that I clone from will have. This is how prototype-based languages work. It feels slightly unusual coming from the class-based background, but I think it makes my Javascript look a lot less alien. I like it.
Let's look at a more complicated example shall we?
"super" is implemented with "this.constructor.prototype". It seems wordy, but prototype on the object is not built-in to Javascript. Besides, you should use "super" sparingly. To me, this reads better and works better for inheritance. I have dropped all references to classes. This makes meta-programming easier as well (I simply walk up the prototype chain with "this.constructor.prototype" and iterate through the properties.
The constructor function used as a class always seemed awkward to me. It was inelegant, but the above fits Javascript coding better. The reason is because I'm now using it as a prototype-based language and not forcing class-based OO on it. The above is meant to get started playing around. Prototype-based programming is so cool and I'm still exploring all of the possibilities. There's little documentation, but the little that is well worth the effort to track down. Have fun!
The example above was tested in SpiderMonkey. A great little REPL for playing with Javascript.
I've been reacquainting myself with Self and Io again. And it hit me like a rhino slamming into me. I've been doing Javascript all wrong. I should have treating it like the prototype-based language that it is. Sure, it doesn't have the ability to inherit from multiple prototypes like Self, but the way to succeed is with prototypes. Forcing class-based OO is like walking up the rainbow and finding no pot of gold at the end.
First, let's write the following:
Object.prototype.clone=function() {
var creator=function() { this.constructor=arguments.callee };
creator.prototype=this;
return new creator();
}
Object.prototype.mixIn=function(definitions) {
for (var each in definitions) if (definitions.hasOwnProperty(each)) {
this[each]=definitions[each];
}
}
It's just two methods up on the Object prototype. Why clone is not part of the Javascript standard is beyond me. Clone is required in all the other prototype-bases languages I have seen. It is the only way to create new objects. Enough complaining, it was only a few lines of code. All my clone method does is make the object I call it on the prototype of the result. I get a clean object with all of the properties of the receiver inherited. Nice. This is the behavior we want. Next, I added a convenience method to Object to mix-in in other objects. This is helpful to keep my code organized. I can just create a hash object with my functions and properties like before. So far, this is standard stuff. But, here is how I use it:
Pounds = new Object();
Pounds.mixIn({
of: function(value) {
var result=this.clone();
result.value=value;
return result;
},
toString: function() {
return this.value.toString() + " lbs";
},
value: 0
});
print(Pounds.of(5)); // => 5 lbs
print(Pounds); // => 0 lbs
print(Pounds.isPrototypeOf(Pounds.of(5))); // => true
Notice, normally, you define the constructor with the first letter of the name upper cased. I no longer need the constructor, so I upper case on the prototype that will be the example for all the instances that I clone off it. The example above is a measurement class. "Pounds" is my example so I default it with values that the objects that I clone from will have. This is how prototype-based languages work. It feels slightly unusual coming from the class-based background, but I think it makes my Javascript look a lot less alien. I like it.
Let's look at a more complicated example shall we?
Animal = new Object();
Animal.mixIn({
name: "Unknown",
sound: function() {
return "?";
},
toString: function() {
return this.name
+ " goes " + this.sound()
+ " and weighs "
+ this.weight.toString();
},
weight: Pounds.of(0)
});
Cat = Animal.clone();
Cat.mixIn({
name: "Unknown Cat",
sound: function() {
return "Meow";
},
weight: Pounds.of(10)
});
grendel = Cat.clone();
grendel.mixIn({
name: "Grendel",
sound: function() {
return this.constructor.prototype.sound.call(this) + " and Purr";
},
weight: Pounds.of(20)
});
gracie = Cat.clone();
gracie.mixIn({
name: "Gracie",
sound: function() {
return "Purr";
}
});
print(Animal); // => Unknown goes ? and weighs 0 lbs
print(Cat); // => Unknown Cat goes Meow and weighs 10 lbs
print(Animal.isPrototypeOf(grendel)); // => true
print(grendel); // => Grendel goes Meow and Purr and weighs 20 lbs
print(gracie); // => Gracie goes Purr and weighs 10 lbs
"super" is implemented with "this.constructor.prototype". It seems wordy, but prototype on the object is not built-in to Javascript. Besides, you should use "super" sparingly. To me, this reads better and works better for inheritance. I have dropped all references to classes. This makes meta-programming easier as well (I simply walk up the prototype chain with "this.constructor.prototype" and iterate through the properties.
The constructor function used as a class always seemed awkward to me. It was inelegant, but the above fits Javascript coding better. The reason is because I'm now using it as a prototype-based language and not forcing class-based OO on it. The above is meant to get started playing around. Prototype-based programming is so cool and I'm still exploring all of the possibilities. There's little documentation, but the little that is well worth the effort to track down. Have fun!
The example above was tested in SpiderMonkey. A great little REPL for playing with Javascript.
Monday, April 14, 2008
Missing Explanations
I was looking over my last post and forgot that I didn't discuss these two methods below:
It might seem a little overkill to have the everytimeButFirst function, but I think it reads better in the method and communicates the intent. Normally, you could implement putting in the comma in between items in the collection like so:
It's a little bit longer. I hate the boolean variable "shouldAddComma". I really do. It just doesn't read well. It's hard to see what's going on. The naming makes it better. But, it's just adding unnecessary noise.
But, all is not well in the first version that I used either. Not all programmers are versed in functional programming, but even a functional programmer would scoff at the first version. Why? It changes state. Plus, the implementation of everytimeButFirst while clever would not be obvious. Basically, what you're seeing is my experiment in using nothing but functions instead of a boolean. Fun for blogging and brain stretching, but not for production systems. Clever is the enemy of the maintenance programmer. But, what if we did this:
You might say I just displaced the boolean to somewhere lese and you would be right. But, I got it out of the method toString which is where I didn't like it. It's safely behind a wall where it makes sense to have. The internal implementation of everyTimeButFirst was too clever the first time around. It is still using higher-order functions, but one is easier to understand than nested ones that change themselves out.
Remember I said the original implementation would make a functional programmer gag because of the side-effects. We could make it side-effect free by making it recursive. But, Javascript is not optimized for tail-recursion. So, I did what I thought was best.
Function.prototype.everyTimeButFirst=function() {
var self=this;
var toCall=function() {
toCall=self;
return null;
};
return function() {
return toCall.apply(this, arguments);
};
}
Array.prototype.toString=function() {
var result="[";
var addComma=function() { result = result + ", " };
var addCommaOnlyAfterFirst=addComma.everyTimeButFirst();
Array.prototype.each.call(this, function(every) {
addCommaOnlyAfterFirst();
result = result + every;
});
return result + "]";
}It might seem a little overkill to have the everytimeButFirst function, but I think it reads better in the method and communicates the intent. Normally, you could implement putting in the comma in between items in the collection like so:
Array.prototype.toString=function() {
var result="[";
var shouldAddComma=false;
Array.prototype.each.call(this, function(every) {
if (shouldAddComma) {
result = result + ","
} else {
shouldAddComma=true;
}
result = result + every;
});
return result + "]";
}
It's a little bit longer. I hate the boolean variable "shouldAddComma". I really do. It just doesn't read well. It's hard to see what's going on. The naming makes it better. But, it's just adding unnecessary noise.
But, all is not well in the first version that I used either. Not all programmers are versed in functional programming, but even a functional programmer would scoff at the first version. Why? It changes state. Plus, the implementation of everytimeButFirst while clever would not be obvious. Basically, what you're seeing is my experiment in using nothing but functions instead of a boolean. Fun for blogging and brain stretching, but not for production systems. Clever is the enemy of the maintenance programmer. But, what if we did this:
Function.prototype.everyTimeButFirst=function() {
var shouldExecute=false;
return function() {
if (shouldExecute) {
return toCall.apply(this, arguments);
} else {
shouldExecute=true;
return null;
}
};
}You might say I just displaced the boolean to somewhere lese and you would be right. But, I got it out of the method toString which is where I didn't like it. It's safely behind a wall where it makes sense to have. The internal implementation of everyTimeButFirst was too clever the first time around. It is still using higher-order functions, but one is easier to understand than nested ones that change themselves out.
Remember I said the original implementation would make a functional programmer gag because of the side-effects. We could make it side-effect free by making it recursive. But, Javascript is not optimized for tail-recursion. So, I did what I thought was best.
Sunday, April 13, 2008
"Super" was wrong
My implementation of "super" was wrong. I did an implementation in this blog post. It was wrong for several reasons. The number one reason was because it was too complex. The first hint that it was too complex was when I was setting the "constructor" property manually. This is done for you and only needs to change if you set the constructor's "prototype" property with "{}" or "new Object()". I was guilty of the this sin. Turns out if I play by the rules, I don't need the "subclassFrom" function nor do I need to add the special "super" properties. It's actually less verbose and it's playing by the Javascript rules. When in Rome, do as the Romans.
My second mistake was that I thought each object had an immutable property "prototype". This is why I was getting "undefined" when I asked for it. I should have known that I was wrong and not the implementation. Anyway, my belief was WAY WRONG. I don't know where I got this piece of mythology from. I think I pulled it from the sky. The truth is that the "prototype" property is only on Function objects. It's set on the objects it constructs and it is not available. Mozilla and Adobe implementations have a property "__proto__" that stores it, but it is not in the standard and thus, not to be used. All objects by the standard should get their prototype from their "constructor" property. Learn something new everyday.
For the new implementation, I got rid of the "subclassFrom". It's not needed now and I'm only left with the "methods" function from before. It now simply moves properties from one object to another. It's only for syntactic shorthand now. I did add something new: function "proto". It's "super" basically. Here's the implementation:
So, how do you do super by playing by the rules? Here's how:
Output from the above:
Notice the "this.proto().constructor.call" in the Sub constructor function, it expands to "this.constructor.prototype.constructor.call". This is calling the "super" constructor. We could also do "arguments.callee.prototype.constructor.call" instead, but really it's a lot to type in isn't it? We also couldn't put that into a function as easily without calling "arguments.callee".
I got a better implementation and something that's more like Javascript. I like keeping my Javascript close to what a Javascript developer would expect. Prototype-based programming is powerful and it's worth exploring things without classes. But, that's a small digression. All I wanted was super and some shorthands for grouping my methods. I have that now.
My second mistake was that I thought each object had an immutable property "prototype". This is why I was getting "undefined" when I asked for it. I should have known that I was wrong and not the implementation. Anyway, my belief was WAY WRONG. I don't know where I got this piece of mythology from. I think I pulled it from the sky. The truth is that the "prototype" property is only on Function objects. It's set on the objects it constructs and it is not available. Mozilla and Adobe implementations have a property "__proto__" that stores it, but it is not in the standard and thus, not to be used. All objects by the standard should get their prototype from their "constructor" property. Learn something new everyday.
For the new implementation, I got rid of the "subclassFrom". It's not needed now and I'm only left with the "methods" function from before. It now simply moves properties from one object to another. It's only for syntactic shorthand now. I did add something new: function "proto". It's "super" basically. Here's the implementation:
Function.prototype.methods=function(funcs) {
for (each in funcs) if (funcs.hasOwnProperty(each)) {
this.prototype[each]=funcs[each];
}
}
Object.prototype.proto=function() {
return this.constructor.prototype;
}
So, how do you do super by playing by the rules? Here's how:
Function.prototype.methods=function(funcs) {
for (each in funcs) if (funcs.hasOwnProperty(each)) {
this.prototype[each]=funcs[each];
}
}
function Base() {
print("base constructor called");
}
Base.prototype.toString=function() { return "aBase"; }
function Sub() {
this.proto().constructor.call(this);
print("sub constructor called");
}
Sub.prototype=new Base();
Sub.prototype.toString=function() { return this.proto().toString.call(this) + " and aSub"; }
Output from the above:
base constructor called
********
base constructor called
aBase
********
base constructor called
sub constructor called
aBase and aSub
Notice the "this.proto().constructor.call" in the Sub constructor function, it expands to "this.constructor.prototype.constructor.call". This is calling the "super" constructor. We could also do "arguments.callee.prototype.constructor.call" instead, but really it's a lot to type in isn't it? We also couldn't put that into a function as easily without calling "arguments.callee".
I got a better implementation and something that's more like Javascript. I like keeping my Javascript close to what a Javascript developer would expect. Prototype-based programming is powerful and it's worth exploring things without classes. But, that's a small digression. All I wanted was super and some shorthands for grouping my methods. I have that now.
Annotations and Aspects in Javascript
Here's the moment, I've been building up to:
Here's the output:
Not much to explain at all. I think the code speaks for itself. The output shows the arguments passed in and what the results were from the call. I didn't return anything from either method, but it wouldn't be hard to verify that it does indeed work. I implemented my own "toString" for Arrays to print out the arguments and it's worth looking at. "arguments" is not an array, but we can call array functions on it. Most of the built-in Array functions can be called on any object. You just have to use the wordy "Array.prototype.functionName.call" to use it.
I wrote this for this blog post, but I'm planning on beefing it up with exception handling and un-weaving among other things. I also plan on adding more tests to my test suite that I did not show. The purpose was to show some cool tricks in Javascript and I hope it was fun.
And here's the entire implementation once more:
var logAround=function(func,name) {
this[name]=defineAround(function(proceedFunc) {
print("before: "+name+" "+Array.prototype.slice.call(arguments,1));
var result=proceedFunc();
print("after: "+name+" "+result);
return result;
}, func);
}
var doesItLog=function(each) {
return each.log == true;
}
Transaction.prototype.eachFunction(logAround.onlyWhen(doesItLog));
var test=new Transaction();
test.begin();
test.commit();Here's the output:
js> load("aspect.js")
before: begin []
begin
after: begin undefined
before: commit []
commit
after: commit undefinedNot much to explain at all. I think the code speaks for itself. The output shows the arguments passed in and what the results were from the call. I didn't return anything from either method, but it wouldn't be hard to verify that it does indeed work. I implemented my own "toString" for Arrays to print out the arguments and it's worth looking at. "arguments" is not an array, but we can call array functions on it. Most of the built-in Array functions can be called on any object. You just have to use the wordy "Array.prototype.functionName.call" to use it.
I wrote this for this blog post, but I'm planning on beefing it up with exception handling and un-weaving among other things. I also plan on adding more tests to my test suite that I did not show. The purpose was to show some cool tricks in Javascript and I hope it was fun.
And here's the entire implementation once more:
function defineBefore(beforeFunc, proceedFunc) {
return function() {
beforeFunc.apply(this,arguments);
return proceedFunc.apply(this, arguments);
};
}
function defineAfter(afterFunc, proceedFunc) {
return function() {
var result=proceedFunc.apply(this, arguments);
afterFunc.apply(this,arguments);
return result;
};
}
function defineAround(aroundFunc, proceedFunc) {
return function() {
var args=Array.prototype.slice.call(arguments,0);
args.unshift(proceedFunc.bindTo(this));
return aroundFunc.apply(this, args);
};
}
Function.prototype.bindTo=function(thisObject) {
var selfFunc=this;
return function() {
return selfFunc.apply(thisObject, arguments);
};
}
Function.prototype.everyTimeButFirst=function() {
var self=this;
var toCall=function() {
toCall=self;
return null;
};
return function() {
return toCall.apply(this, arguments);
};
}
Function.prototype.onlyWhen=function(ruleFunc) {
var self=this;
return function() {
if (ruleFunc.apply(this, arguments))
return self.apply(this, arguments);
}
}
Object.prototype.each=function(everyFunc) {
for (var name in this) if (this.hasOwnProperty(name)) {
everyFunc.call(this, this[name],name);
}
}
Object.prototype.eachFunction=function(everyFunc) {
this.each(everyFunc.onlyWhen(function(every) {
return every.constructor == Function;
}));
}
Object.prototype.run=function(func) {
func.call(this);
}
Object.prototype.define=function(name, annotations, func) {
this[name]=func;
annotations.each(function(each, name) {
func[name]=each;
});
}
Array.prototype.each=function(everyFunc) {
for (var index=0; index < this.length; index++)
everyFunc.call(this, this[index], index)
}
Array.prototype.toString=function() {
var result="[";
var addComma=function() { result = result + ", " };
addComma=addComma.everyTimeButFirst();
Array.prototype.each.call(this, function(every) {
addComma();
result = result + every;
});
return result + "]";
}
Annotations in Javascript
Last post, I talked about how to implement crude aspect advices. I say crude because the implementation would need to be beefed up a bit for wider use. The ideas were more important. I wanted to spend the article on the tricky bits of implementation. I'll take the same tactic with this article.
Let's start with what our code will look like. In fact, let's implement something everyone is familiar with: a transaction. Now, our transaction will have a blank implementation (we'll print out the important bits). It's the API that we will care about later. Here's the definition:
OK. There's some new functions named "run" and "define". I'll show their implementations soon. You can probably guess the implementation of "run". It's simply so that my hands don't get tired typing "Transaction.prototype". I could use "with {}", but I have found its implementation inconsistent among Javascript dialects. The next new function, "define", is how we're going to define our annotations. It's a shorthand for better readability and to reduce duplication. All it will do is add the function to our object and add the annotations as properties. Annotations are simple in Javascript because functions are just objects and we can add anything we want to them. How cool.
Here's the implementations:
Both are straightforward. But, I introduced another function: "each". Those familiar with Ruby will notice what it does right away. For the non-Rubyists, it iterates over all the properties of the object. My implementation also sends the name of the property as an extra parameter. Here's how I did "each":
It basically allows me not to have a "for" loop. Simple. You might have noticed my use of "call". The reason is because I wanted to pass along "this" to the function passed in.
That is it for implementing annotations. The query language is already built in (albeit a little verbose). We only have to iterate over the functions of an object. Here's some code I would like to use to test my annotations and query implementation:
Oh boy. Can you guess the output from the above? Here it is:
The annotations I have is to mark a function to be logged on entry and exit. I'll spend the rest of the article on the implementation and bring together the annotations, aspects, and logging in the next article.
Let's talk about the new functions: "onlyWhen" and "eachFunction". I think you can guess what each of them do. "onlyWhen" is defined on a function and takes a function to check the arguments for some condition. If the condition is true, it executes the receiver function. It returns a function that brings all of this together. This is more functional programming at work. "eachFunction" takes a function that will be called for each function that is a value of a property on the object.
Like always, here's how I implemented them:
In the "onlyWhen" implementation, I have to bind "this" (the function) to self so that we can use it later in the function that we use a result. "this" will be bound to a different object. "eachFunction" brings together the functions "each" and "onlyWhen".
That's it! You could of course add implementations to define annotations so that we make sure that only pre-defined ones are used in functions. I'll leave that as an exercise to the reader. It wouldn't take much to implement it. The next article will put everything together. All we have to do now is weave based on rules. We have the means to iterate over functions and we have the means to replace implementations through our advices. The next article will mix this batter.
Let's start with what our code will look like. In fact, let's implement something everyone is familiar with: a transaction. Now, our transaction will have a blank implementation (we'll print out the important bits). It's the API that we will care about later. Here's the definition:
function Transaction() {
}
Transaction.prototype.run(function() {
this.define(
"begin",
{log: true},
function() {
print("begin");
});
this.define(
"commit",
{log: true},
function() {
print("commit");
});
this.define(
"rollback",
{log: true},
function() {
print("rollback");
});
this.toString=function() {
return "i am transaction";
}
});OK. There's some new functions named "run" and "define". I'll show their implementations soon. You can probably guess the implementation of "run". It's simply so that my hands don't get tired typing "Transaction.prototype". I could use "with {}", but I have found its implementation inconsistent among Javascript dialects. The next new function, "define", is how we're going to define our annotations. It's a shorthand for better readability and to reduce duplication. All it will do is add the function to our object and add the annotations as properties. Annotations are simple in Javascript because functions are just objects and we can add anything we want to them. How cool.
Here's the implementations:
Object.prototype.run=function(func) {
func.call(this);
}
Object.prototype.define=function(name, annotations, func) {
this[name]=func;
annotations.each(function(each, name) {
func[name]=each;
});
}Both are straightforward. But, I introduced another function: "each". Those familiar with Ruby will notice what it does right away. For the non-Rubyists, it iterates over all the properties of the object. My implementation also sends the name of the property as an extra parameter. Here's how I did "each":
Object.prototype.each=function(everyFunc) {
for (var name in this) if (this.hasOwnProperty(name)) {
everyFunc.call(this, this[name],name);
}
}It basically allows me not to have a "for" loop. Simple. You might have noticed my use of "call". The reason is because I wanted to pass along "this" to the function passed in.
That is it for implementing annotations. The query language is already built in (albeit a little verbose). We only have to iterate over the functions of an object. Here's some code I would like to use to test my annotations and query implementation:
var every=function(each,name) {
print(name);
}
var doesItLog=function(each) {
return each.log == true;
}
Transaction.prototype.eachFunction(every.onlyWhen(doesItLog));
Oh boy. Can you guess the output from the above? Here it is:
begin
commit
rollback
The annotations I have is to mark a function to be logged on entry and exit. I'll spend the rest of the article on the implementation and bring together the annotations, aspects, and logging in the next article.
Let's talk about the new functions: "onlyWhen" and "eachFunction". I think you can guess what each of them do. "onlyWhen" is defined on a function and takes a function to check the arguments for some condition. If the condition is true, it executes the receiver function. It returns a function that brings all of this together. This is more functional programming at work. "eachFunction" takes a function that will be called for each function that is a value of a property on the object.
Like always, here's how I implemented them:
Function.prototype.onlyWhen=function(ruleFunc) {
var self=this;
return function() {
if (ruleFunc.apply(this, arguments))
return self.apply(this, arguments);
}
}
Object.prototype.eachFunction=function(everyFunc) {
this.each(everyFunc.onlyWhen(function(every) {
return every.constructor == Function;
}));
}In the "onlyWhen" implementation, I have to bind "this" (the function) to self so that we can use it later in the function that we use a result. "this" will be bound to a different object. "eachFunction" brings together the functions "each" and "onlyWhen".
That's it! You could of course add implementations to define annotations so that we make sure that only pre-defined ones are used in functions. I'll leave that as an exercise to the reader. It wouldn't take much to implement it. The next article will put everything together. All we have to do now is weave based on rules. We have the means to iterate over functions and we have the means to replace implementations through our advices. The next article will mix this batter.
Friday, April 11, 2008
Aspects in Javascript
Just like I promised! I'm going to describe how to do aspects in Javascript. Now, this example will be simplified. You will probably want to beef up the implementation given here. I'm really showing off an idea and how you can apply it to your Javascript libraries. I did this for fun and was shocked how easy it was. In these examples, I will be using Spidermonkey.
I'm first going to show off how to implement advices. Let's start with "before" advice and then have a simple test for our implementation. I would recommend using JSUnit for testing. I'm simply going to output it for demonstration purposes.
The easiest advice to implement is "before". All we need to do is define a function that creates a new function that calls our before function and then calls the function we originally wanted to call. "defineBefore" handles this quite nicely. The rest of the code below is defining our "before" advice and the function we want to call and then doing the wrapping. Pretty simple.
Here's the output:
You can see from the results that our "before" advice implementation can look at the arguments (but, not change them, we'll get to that). And be basically benign to the whole operation. Our weaving works!
"After" advice is equally as easy. We just need to remember the result and return that from our weaved function. Again, the "after" function will be benign and not be able to change the result. Here's the implementation:
Here's the results:
Now, our "before" and "after" advice weaving did not allow us to change the arguments or results. I wanted to keep it simple without a lot of complications. If we need to change the arguments or tamper with the result, let's do it with an "around" advice.
The implementation for "around" is a little bit more complicated. I want to make calling the proceed function as simple as possible in the after advice function. To do this, I need to wrap the proceed function with another function that will bind the "this" so that we don't have to worry with sending "call" on the proceed function. The implementations before didn't have to deal with the proceed function in the advice and that made life easier. Now, we'll have that control and with that power, comes the ability to change arguments and results. Here's the implementation:
And where would we be without the results?
One more detail, I didn't do an error handling or recovery. You will probably want to wrap any kind of exceptions that might happen in the proceed function and take appropriate action.
So far, our implementation is nice and clean. We're mainly using functional programming concepts for it. The next steps is writing the implementation for the pointcuts and combining that with what we did here. I'll also going to show how to define annotations. Trust me it's going to get more fun as we combine the batter and get ready to bake!
I'm first going to show off how to implement advices. Let's start with "before" advice and then have a simple test for our implementation. I would recommend using JSUnit for testing. I'm simply going to output it for demonstration purposes.
The easiest advice to implement is "before". All we need to do is define a function that creates a new function that calls our before function and then calls the function we originally wanted to call. "defineBefore" handles this quite nicely. The rest of the code below is defining our "before" advice and the function we want to call and then doing the wrapping. Pretty simple.
function defineBefore(beforeFunc, proceedFunc) {
return function() {
beforeFunc.apply(this,arguments);
return proceedFunc.apply(this, arguments);
};
}
function printArg(x) {
print("proceed: " + x);
return x + 1;
}
before=function(x) {
print("before: " + x);
}
printArg=defineBefore(before, printArg);
print("result: "+printArg(6));
Here's the output:
js> load("aspect.js")
before: 6
proceed: 6
result: 7
You can see from the results that our "before" advice implementation can look at the arguments (but, not change them, we'll get to that). And be basically benign to the whole operation. Our weaving works!
"After" advice is equally as easy. We just need to remember the result and return that from our weaved function. Again, the "after" function will be benign and not be able to change the result. Here's the implementation:
function defineAfter(afterFunc, proceedFunc) {
return function() {
var result=proceedFunc.apply(this, arguments);
afterFunc.apply(this,arguments);
return result;
};
}
after=function(x) {
print("after: " + x);
}
printArg=defineAfter(after, printArg);
print("result: "+printArg(8));
Here's the results:
js> load("aspect.js")
before: 8
proceed: 8
after: 8
result: 9
Now, our "before" and "after" advice weaving did not allow us to change the arguments or results. I wanted to keep it simple without a lot of complications. If we need to change the arguments or tamper with the result, let's do it with an "around" advice.
The implementation for "around" is a little bit more complicated. I want to make calling the proceed function as simple as possible in the after advice function. To do this, I need to wrap the proceed function with another function that will bind the "this" so that we don't have to worry with sending "call" on the proceed function. The implementations before didn't have to deal with the proceed function in the advice and that made life easier. Now, we'll have that control and with that power, comes the ability to change arguments and results. Here's the implementation:
Function.prototype.bindTo=function(thisObject) {
var selfFunc=this;
return function() {
return selfFunc.apply(thisObject, arguments);
};
}
function defineAround(aroundFunc, proceedFunc) {
return function() {
var args=Array.prototype.slice.call(arguments,0);
args.unshift(proceedFunc.bindTo(this));
return aroundFunc.apply(this, args);
};
}
function concatAndPrint(first,second) {
print("first: "+first);
print("second: "+second);
var result=first + second;
print("concat result: "+ result);
return result;
}
around=function(proceedFunc, first, second) {
print("around first: "+first);
print("around second: "+second);
var result=proceedFunc(first, second);
return result + "c";
}
concatAndPrint=defineAround(around, concatAndPrint);
print("final result: "+concatAndPrint("a","b"));
And where would we be without the results?
js> load("aspect.js")
around first: a
around second: b
first: a
second: b
concat result: ab
final result: abc
One more detail, I didn't do an error handling or recovery. You will probably want to wrap any kind of exceptions that might happen in the proceed function and take appropriate action.
So far, our implementation is nice and clean. We're mainly using functional programming concepts for it. The next steps is writing the implementation for the pointcuts and combining that with what we did here. I'll also going to show how to define annotations. Trust me it's going to get more fun as we combine the batter and get ready to bake!
Tuesday, April 08, 2008
Javascript Inheritance with super
One thing that has always bothered me about Javascript is there is no implementation of "super". Most texts suggest to simply call the super function explicitly via its prototype. It makes for refactoring your inheritance hierarchy no fun because of the direct calls. And let's not mention all the duplication.
Let's think for a minute. Everything in Javascript is an object. What if we added the super automatically to the overriden functions so we could get access to it? And while we are at it, why not make our object definitions a bit more explicit along the way?
So, I whipped up the following code:
It's two very short functions. But, it allows me to do this:
"arguments.callee.superFunction.call" is a little verbose, but it's better than duplicating the name of my "super" implementation prototype all over the place. Plus, how often do you call "super". I generally think too many calls to "super" is a design smell.
I like this approach mostly. The only thing I don't like is the names I chose. But, I'll keep working on it. I was just happy in two functions, I have "super" in my constructors and functions. If anything, it's a different way of thinking about the problem.
Coming next, how to do aspects and annotations in Javascript.
Let's think for a minute. Everything in Javascript is an object. What if we added the super automatically to the overriden functions so we could get access to it? And while we are at it, why not make our object definitions a bit more explicit along the way?
So, I whipped up the following code:
Function.prototype.subclassFrom=function(superClassFunc) {
if (superClassFunc == null) {
this.prototype={};
} else {
this.prototype=new superClassFunc();
this.prototype.constructor=this;
this.superConstructor=superClassFunc;
}
}
Function.prototype.methods=function(funcs) {
for (each in funcs) if (funcs.hasOwnProperty(each)) {
var original=this.prototype[each];
funcs[each].superFunction=original;
this.prototype[each]=funcs[each];
}
}
It's two very short functions. But, it allows me to do this:
function Parent(z) {
this.z=z;
}
Parent.subclassFrom(null);
Parent.methods({
methodOne: function(x) {...},
methodTwo: function() {...}
});
function Child(z,y) {
arguments.callee.superConstructor.call(this,z);
this.y=y;
}
Child.subclassFrom(Parent);
Child.methods({
methodOne: function(x) {
arguments.callee.superFunction.call(this,x);
...
},
methodThree: function() {...}
});
"arguments.callee.superFunction.call" is a little verbose, but it's better than duplicating the name of my "super" implementation prototype all over the place. Plus, how often do you call "super". I generally think too many calls to "super" is a design smell.
I like this approach mostly. The only thing I don't like is the names I chose. But, I'll keep working on it. I was just happy in two functions, I have "super" in my constructors and functions. If anything, it's a different way of thinking about the problem.
Coming next, how to do aspects and annotations in Javascript.
Friday, May 11, 2007
Truth, Justice, And The American Way
There's one subtle feature of some languages that keeps causing me pain and in the wrong hands causes more harm than good. What is this feature? Let me show you some Javascript code:
Nothing wrong here, from the looks of it the code is checking if the transaction has an amount defined and then marks the transaction valid or invalid. Simple right? But, what if an amount is defined and it is zero? You would think the transaction is marked valid right? WRONG! It will be marked invalid because anything that's zero, nil, or undefined in Javascript is considered false.
And that's my beef, why not treat booleans with their own type. Why treat any other value as equivalent? Subtle bugs like the one above are infuriating to me. The simple reason is that they can easily be avoided with a few extra characters.
The moral of this story is to code exactly what you mean. Be specific. Don't rely on arcane language features to save a few key strokes. Java and Smalltalk do the right thing and make you use boolean types.
if (transaction.amount) {
transaction.markValid();
} else {
transaction.markInvalid();
}
Nothing wrong here, from the looks of it the code is checking if the transaction has an amount defined and then marks the transaction valid or invalid. Simple right? But, what if an amount is defined and it is zero? You would think the transaction is marked valid right? WRONG! It will be marked invalid because anything that's zero, nil, or undefined in Javascript is considered false.
And that's my beef, why not treat booleans with their own type. Why treat any other value as equivalent? Subtle bugs like the one above are infuriating to me. The simple reason is that they can easily be avoided with a few extra characters.
if (transaction.amount == undefined) {
transaction.markValid();
} else {
transaction.markInvalid();
}
The moral of this story is to code exactly what you mean. Be specific. Don't rely on arcane language features to save a few key strokes. Java and Smalltalk do the right thing and make you use boolean types.
Subscribe to:
Posts (Atom)
