About : libVSC [1]
As I was thinking about writing a short presentation about libVSC, I'll try to order my thoughts about it in a series of articles, just to provide a foundation for any future such work.
The import() function.
I shamelessly stole this one from Python, but I think I managed to provide a pretty good alternative to ugly code that results from deep include() statements. Here's a quick example from the Zend Framework:
/** @see Zend_View_Interface */
require_once 'Zend/View/Interface.php';
// ... snip
abstract class Zend_View_Abstract implements Zend_View_Interface {
// ... snip
Granted, it's not so bad just looking at one file, but when you have a big project that uses the framework you'll need to include some more stuff. In the end, the beginning of your files would contain a big pile of include() statements, enough to discourage anyone from venturing further.
Coming back to the import() function. It's purpose is very similar, albeit in a smaller scope, with its Python counterpart. Basically it interprets the received parameter as a path and tries to create a new one iterating over the existing ones in the include paths array. When it finds a valid folder it adds it to the list. As an example:
/**
* The include path would look something like this initially
* "/home/habarnam/workspace/vsc-v2/lib/"
*/
import ('domain');
/**
* After the call it would be
* "/home/habarnam/workspace/vsc-v2/lib/"
* "/home/habarnam/workspace/vsc-v2/lib/domain/"
*/
import ('access');
/**
* After the call it would be
* "/home/habarnam/workspace/vsc-v2/lib/"
* "/home/habarnam/workspace/vsc-v2/lib/domain/"
* "/home/habarnam/workspace/vsc-v2/lib/domain/access/"
*/
In my biased eye, it looks cleaner. Since this only adds folders to the include path, we need a simple __autoload() to actually load the file we need in the execution scope. A full example would look something like this:
// adds /home/habarnam/workspace/vsc-v2/lib/domain/models to the include paths
import ('domain/models');
// __autoload function finds the /home/habarnam/workspace/vsc-v2/lib/domain/models/vscmodela.class.php file and includes it
class vscEmptyModel extends vscModelA {
// ...snip
In the end there's no more need for long underscored names and long include paths as we have a simpler method for including the needed classes.
Of course, this method has its downsides. A first one is that this only works for entities capable of being included by an __autoload() call, namely classes and interfaces. If you need to include other types of files, you'll need to use the include/require mechanism. In my mind, this isn't actually a downside, but provides a cleaner separation between the logic of your application and other types of resources you might be needing.
Another problem is that makes the code a little harder to debug, since you don't know if your desired path has actually been loaded. Of course that when it fails it provides good feedback using the Exceptions handling mechanisms of libVSC (of which I need to write about at another time). Also I am planning to add to them the include paths data, so it provides a better debug method. On the other hand I don't really know how Python deals with this type of errors, so I might check that out too, to have a better understanding.
A final issue I see with it is performance. It is a piece of code that gets called a lot, the __autoload() part of it at least, and I need to be careful to not over extend the execution time needlessly. Also when the include paths list gets bigger might prove a bit challenging to import() new paths, but as of this moment I haven't really had problems.
These being said, you can check the code on my Gitorious repository and any feedback is welcome.
- [ permalink ]
