It's been a tough last month, but now my two last math exams are finally over, and I'm focusing the scathered remains of brain activity on JDevTools, trying to make up for the time lost in rehearsal of Greens formula and the like. Fortunately the time hasn't been lost completely as I've made it a habit to start my day walking the 5 kilometers to school on the banks of Lac Leman, thinking about the project and how I would attack it once I could get coding again.
A topic that has special interest at this point in the phase has been the script engine. As many of you hopefully knows, JDevTools aims to make the life easier for developers taking the footwork out of joomla development. To make a system that's flexible for advanced users, I decided together with my mentor to make a scripting system and then provide a bunch of pre made scripts for those who'd rather take the easy way out. A script system however needs to be easy to use and easy to extend to be useful at all, but if it isn't powerful it wont be all that useful. I'm aiming to achieve both, but how to get there is what's been on my mind lately.
I promise not to dive in to the details for today. That will wait for the moment I actually have a working machinery churning happily away to show for it. Instead I'll be musing a little about the challenges creating a script engine in php consists of, and how I general chose to respond to these challenges so far.
PHP or not PHP
The first question I had to answer was whether the scripts should consist of PHP code, or be made out of something entirely different. XML as it's used for parameters in joomla could be a good example of an alternative format to write the script in, and an alternative script form would certainly have the advantage of being more succinct, since it wouldn't be suffering under the syntax of php.
The advantage of letting scripts consist of php code on the other hand is that developers using JDevTools will (hopefully) already be familiar with php, minimizing the chance of syntax errors. The other big advantage is that the only thing I need to do in order to parse a php script, is to write it out to a temporary file and include it. Et voila, a big bunch of potential nasty bugs is weeded out that way. The challenge remains to make the scripts as usable as possible within the limits of PHP's parsing.
Code Style -> Snippets
Having used javascript for a fair share of web projects, I have developed a huge respect for JQuery and the way it uses object oriented properties to string methods of a property together. For those who are unfamiliar with JQuery here is a made up example:
$script->component("blip")->addView("blop")->addController("Blyp")->to("Blyp")->addTask("edit");
// Adds a component named "blip", with a view named "blop" and a controller with an identifier "blyp";
// The go() takes us to the controller, to which we add a task "edit".
The example might be a little contrieved, but in general I find that this style of coding has the advantage of both being very compact and very easy to understand. There is a clear path from left to right of actions being applied to the component. Another advantage to this method is that the seperation of methods into small simple functions decreases the amount of parameters needed to change things around. Something that often confuses me when I'm learning new syntax normally.
I should mention that this is only an example, and while I got the code down for this functionality, the names and parameters will probably change with time.
Code style -> Blocks
Of course a script would soon be a mess in a big script if everything had to be stringed on the end of another method, so I want it to be simple for developers to break code away in blocks and combine them later. If we for example wanted to declare a database table in it's own block we would do this:
$table = JDevTools::Database();
$table->addRow("id","int")->auto_increment()->unsigned();
$table->addRow("name","text")->default("Giorgio Moroder");
If we then wanted to add this table to our component named "blip" we would could do this:
$script->to("blip")->setTable($table);
That way it's simple to break off parts of the script into blocks of functionality and add it together when it's relevant. This makes it easy to structure scripts and easier for other people to understand the logic flow of larger scripts.
Modularity
All these methods needs to be declared somewhere, and it shouldn't be neccesary to edit the code in 10 places to add a new method to databases. This might not be directly relevant for developers making scripts, but for us who will be writing methods to use with JDevTools, it's important that there is an easy an consistent way to write them and add them to the code. For this purpose I've found PHP's magic methods very useful. Normally when a method is added to a class, it's neccesary to edit the file where the class resides to implement the method, which would soon create a file bloated beyong belief. Fortunately with the magic method __call(), I can make a standard method for dealing with calls to methods that doesn't exist. __call() takes to parameters, the name of the method called and the arguments in an array.
In my case, I check a subfolder called 'methods' for to see if a file with the name called exists. If a file with this name exists, I include the file and create an instance of a class with the same name within the file, passing the arguments recieved by the __call() method to the constructor of the class. It's a quite beautiful way of seperating functionality since every method we would want to use now resides in it's own file, contained in it's own class.
And the result?
Well it's still work in progress, but so far it's shaping up pretty good. I'm hoping to get a couple of test methods running during the week, to weed out errors and bugs. Afterwards the path should be solid for me to focus on writing a bunch of solid methods for most of the common tasks during development, and when they are done, it should be a matter of stringing them together to get something useful out of them.