Intorduction to Class.def
In the first time in 3 years, I've taken a real time off from my jobs. Since programing is one of my largest hobbies, I've been looking around for chalanges to pass the time.
A few days ago, I stumbled upon Def.js. It is an implementation of the Ruby inheritance syntax in JS. It is exactly why I just love JS - it allows you extreme diversity and choise on how you want to write you code.
It took me quite a while to understand what happens there, but eventualy, with the help of [eLad] I found out the class is hacking the valueOf property to make code run when using the << operator
Imediatly, I decided I will create an implementation of this syntax for Mootools' Class.
Problems and Difficulties
First of all, because the way Mootools implements inheritance, I knew I had to use monkey-patching to override the Class constructor.
Next, you'll notice that the syntax that Def.js works with is that the paramaters to the constructor are passed to the new Class' parent. This meant that I had to recognize on Class construction whether it was genuine or a def call. This proves tricky, because if Class.def is called without a numeric operator, things will break.
Another problem was the execution order. It turnes out that the new operator runs before the valueOf (which makes sense) but it also runs before function call, so that meant that Class.def must be used with the new operator. The real problem is that we need to prevent the initialize from running when in inheritance mode, and we can only know we are in inheritance mode after new finished.
I found out that I can create this behavior without the use of the use of valueOf but I decided to use it anyway so to make it less likey that the syntax will be missused.
What came out
I've eventualy came out with this scenario for finding out whether an inheritance action was taking place:
- If
Class.defwas called ,it will trigger the inheritance mode. - When in inhertance mode, any call to a Class constructor (for example
new Person) will create a new Class with the arguments passed to it, with the name used via Class.def.
And the ruslut:
Note that I could have created Person with the normal Class constructor and this code would still work fine, and I can extend Warrior normally with no problems.
Another note is that although this was created to mimic Ruby syntax, you can actualy use any operator that triggers valueOf (for example +, >>, *).
I'm still trying to come up with something that actualy give meaning to the << operator, but for now, you can already use this with ease.
I've created a new version that does use valueOf .