So I am yet again refactoring my code. I hope this is the last time and then I can get into adding behavior.
I did manage to separate all the behaviors and now have seeders, walkers, and shooters working in version 3. But I broke my index page; it is all in Firebug debugging. So waiting until version 4 for the next release.
But as I was doing this, I noticed that I kept passing the parser or the tree around and wondering whether they were in scope when I needed them. And getting confused as to which one I needed. To help highlight what I needed, I decided to make these methods of the objects. And now with my insight of prototype, I decided to attach them to the underlying constructor. The only problem was, well, there was no constructor.
And then it became clear to me that a lot of the fog of my code seems to be coming from that. What prototyping allows one to do is separate the process from the details. And I failed to do that consistently. And so it becomes a mess.
Take as example the tokenizer object. I have struggled with how to make it customizable within the code. So I was making a tokenizer for each parser and passing in options. I think it is fine to still pass in options for initialization, but it might also be nice to switch out relevant components on the fly.
So by putting generic default behavior in the prototype, we can do exactly that. And furthermore, we can overwrite it locally for a short time and then remove it with the delete keyword.
As an example:
var f = function () {}; var g = new f(); //g now uses f.prototype for inheritance. g is an empty object except for that. f.prototype.say = "hi"; console.log(g.say); //hi g.say = "bye"; console.log(g.say); //bye g.say = undefined; console.log(g.say); // undefined in gray box g.say = "back"; console.log(g.say); //back delete g.say; console.log(g.say); //hi
So in our tokenizer, we can have a property for applying the regex as a prototype. This could chunk words, numbers, special characters. But then we hit a comment such as //whatever !!$#!@#$
This comment should be slurped up without pause until the end of the line. Now one can just replace the regex and the next token will be the comment string. No fuss, no muss. And when done, we delete the local override and the tokenizer goes back to its usual parsing. One can envision much more complicated scenarios in which a whole slew of behaviors suddenly morph. That is the power of prototyping.
Of course, this is incredibly dangerous. But when trying to be generic, you either need this or a 10,000 line program. I will stick with the 1000 line kind of program.
Post a Comment