Archives for 2008
The Plan for the Next Few Months
posted on Aug 19, 2008 at 3:22pm with no commentsIt always sucks to write a "sorry for not posting" blog post and so here is the plan for the next few months. PINQ development is temporarily on hold. It's at a point where I like the ideas in it but where the implementation of the packages system is overly complex. My plans are to take a bunch of stuff out of the database and model/gateway areas and move them permanently into the PQL-specific stuff. This makes a lot of sense, especially since I think it would be worthwhile to make PQL as module-like as possible so that I can release it alone for those interested in it.
On the personal development side of things, I have been buying up a huge number of books which I intend to read over the next few/many months. The books that I have queued up to read align nicely with my long-term goals. I just finished reading The C Programming Language (a.k.a. K&R) and am now getting into ANSI Common Lisp. After ANSI CL I plan on reading through Practical Common Lisp (which if you are a longtime reader then you will know I've previously read parts of this book). My main motivation for getting into Common Lisp is that I want to be able to read The Art of the Metaobject Protocol and know exactly what's going on in it.
That's about all there is on the Lisp side of things. I then get into the more systems programmy things that I'm into: language design, compilers, garbage collection, etc. Not too long ago I started reading the dragon book (Compilers: Principles, Techniques, and Tools) and have paused reading of that. It's a dense book so I want to ease into it a bit more. I intend to do that by first reading Programming Language Pragmatics and Compiler Design in C. After those I think I will be ready to finish off the dragon book. Finally, I'm going to jump into Virtual Machines and Garbage Collection: Algorithms for Automatic Dynamic Memory Management
Throughout all of this, I've got side reading of The Pragmatic Programmer and Beautiful Code to read into.
This is my really long term reading schedule. I can imagine reading these books could take me well over a year-- especially now that my third year of university is about to start. School is an increasingly important part of my life, as is my job as a residence advisor at my school and so all of this together will likely limit my blogging ability. However, expect a few random posts now and then, especially around statutory holidays.
Finally, if anyone is ever looking for PHP help, I'm a regular on the SitePoint forums so either create a thread or send me a private message. My username is: Peter Goodman.
See you all on the other side!
Control Flow in PINQ
posted on Jul 16, 2008 at 5:48pm with three comments and tagged with PHP, PINQI was a bit bored so I whipped up this little diagram in OmniGraffle of the control flow within the PINQ framework and an application. Most things will seem familiar to programmers who regularly use MVC frameworks. It's actually slightly more complex than what is going on in there; however, I was limited to using 20 object with the demo version of OmniGraffle and so I was rather limited on what I could show.
The one interesting bit in here is the yield resource exception. As I've written in previous posts, it changes control from one controller to another.
Pythonesque PHP: Self-Documenting Code
posted on Jul 1, 2008 at 6:13pm with two comments and tagged with PHP, Python, PINQOne amazing feature about Python is that it is self-documenting. All classes and functions can have documentation strings and they all have access to them using the __doc__ property. Most Python doc strings follow the conventions in PEP 257 and so when printed out they are usually quite nice.
I decided that I wanted a feature like Python's help() function in PINQ and so I made one using PHP's Reflection API. If you remember (and read my articles) I wrote an earlier blog post about manually rebuilding classes using the Reflector classes.
First, here's an example of the output from my help() function on the Dictionary class in PINQ:
class Dictionary | An array-like class for mapping keys to values. | | Author: Peter Goodman | | Constructor: | | Dictionary([array $default_values]) <==> dict($default_values) | | Public Methods: | | offsetExists(...) | $d->offsetExists($key) <==> isset($d[$key]) | | Check if an entry in this dictionary exists for a given key. | | offsetGet(...) | $d->offsetGet($key) <==> $d[$key] | | Get the value (entry) for a specific key in the dictionary. If the key | does not exist in the dictionary then this function will return NULL. | | offsetSet(...) | $d->offsetSet($key, $val) <==> $d[$key] = $val | $d->offsetSet(NULL, array $val) <==> $d[] = $val | | Map a key in the dictionary to a specific value. | | Note: When specifying the key as NULL, val must be an array. | | offsetUnset(...) | $d->offsetUnset($key) <==> unset($d[$key]) | | Remove a (key,value) entry in the dictionary. | | toArray(...) | $d->toArray(void) -> array | | Return the (key,value) pairs in the dictionary as an array mapping keys | to values. | | Class Descendants: | | InnerRecord | Loader | ConfigLoader | PackageLoader | ModelDictionary | PinqRouteParser | ReadOnlyDictionary | StackOfDictionaries | View | PinqView
As you can see, it gets the PHP Doc Block comments for classes and methods and displays them nicely. It also shows the class constants. I decided not to show class properties because I usually don't do doc-block style commenting on them and so I didn't need them. Another thing this class does is function the extending/implementing classes for an interface/class and shows it as a tree of class descendants. This follows nicely from the idea of self-documenting code as it allows the programmer to discover new and important classes.
I'm currently in the process of re-documenting PINQ's source code to be more Pythonesque as I rather like the format and it suits the help() function well. This, of course, does not mean that my help() function (and its associated functions) do not work for non-PINQ classes because they do.
You can check out/download the code from PINQ's Google Code project repository at http://code.google.com/p/pinq-php/source/browse/trunk/system/functions/reflection.php. The help function works for classes, objects, functions, and class/object methods (using two arguments instead of one).
Yielding Control to a Different Controller
posted on Jun 28, 2008 at 10:44am with three comments and tagged with PHP, PINQRecently I've implemented a very nice feature in PINQ: the ability to yield control to a different controller. The way it works is by throwing a specific exception and the catch for that exception is within a do-while loop. Inside that loop is the code that parses a route, instantiate a controller and dispatch to an action. The catch changes the route to parse and tells the loop to iterate one more time, thus allowing the programmer to change the controller/action being executed.
This feature's main use case is error handling. With a proper error controller set up, such as the one below:
<?php
class ErrorController extends PinqController {
public $layout_file = 'error';
public function ANY_403() { set_http_status(403); }
public function ANY_404() { set_http_status(404); }
public function ANY_405() { set_http_status(405); }
public function ANY_500() { set_http_status(500); }
}
I can then do: yield('/error/404') for example, or more easily do yield(ERROR_404);. This feature allows me to move the presentation logic for errors into controllers that are under the control of the programmer (ie: in the application directory) and also not make common errors not something that needs to be handled separately of the rest of the program.
Another use case is extending the class that causes this change in control flow. For example, my DatabaseException class now causes an error 500 when thrown as usual. Here is the code to do that:
<?php
class DatabaseException extends YieldControlException {
public function __construct($message) {
parent::__construct(ERROR_500);
$this->message = $message;
}
}
I think this is an extremely sweet solution to the problem of gracefully handling certain kinds of errors.
2½ Cool Hacks in PHP
posted on Jun 26, 2008 at 10:12am with no commentsAs I've been testing out lot's of things for my framework, I've come across a few neat little hacks. The first 1.5 hacks involves PHP's list() construct, and possible ArrayAccess as well.
<?php list($foo->bar, $foo) = array(new Bar, new Foo);
Look closely at the order of variables in the list(). It seems that list actually sets the variables from right to left. It also indexes into the array numerically, which means that if instead of putting an array as the rvalue of list, you can put an object that implements ArrayAccess.
The second fun hack uses PHP's ArrayAccess interface (as before) but to overload PHP's array push syntaxt. Consider this valid piece of code that in PINQ merges an array into a dictionary:
<?php
$dict = new Dictionary;
$dict[] = array('foo' => 'bar');
This hack works using ArrayAccess::offsetSet, and recognizing when a NULL key is passed and handling it accordingly.