Thursday, December 23, 2010

Images inheritance in Plack based apps

My plan for Nblog is to let users customize it by subclassing and overloading, in the screencast I showed how to do that with controllers and templates, in the latest revision of Nblog I added the possibility of overloading images. There are Plack components for all parts of this task - but I had a bit of struggle with getting the settings right. Maybe the following code snippet will spare similar time waste for someone?



Some explanations: psgi_callback is the method in WebNano that constructs the anonymous subroutine required by the PSGI standard and here I use the around Moose method modifier for it to add some additional processing there. static_roots returns a list of directories where to search for the static files - this is our search path - the first file found in these directories is served. In the base class this list contains only 'static' - if you want to overload the static files in a subclass you need to add your directories before this one, in my example subclass config I have:

static_root => [ 'static', '../Nblog/static' ]

(these are relative paths). See also Plack::App::Cascade. All of this would be a bit easier to assemble if the Plack components logged some debug info to STDOUT, like what you can find in the standard Apache logs about files not found, when run in development environment. I am volunteering to write a patch if there is a green light from the core devs.

Monday, December 20, 2010

Unit Testing

With one functional/system test you can test lot's of low level parts that in Unit Testing would require a separate test each. It is also easier to write - because you only need to test how the module/library is used and using it should be easy (and not require mocking etc) - otherwise the library would not be a good library to start with. And what are the reasons to do unit testing? Personally I was never convinced by the arguments until I started reading Misko Hevery - here is for example is the single best explanation of why to do unit testing I've ever seen:

Lets say you would like to test a car, which you are in the process of designing, would you test is by driving it around and making modifications to it, or would you prove your design by testing each component separately? I think that testing all of the corner cases by driving the car around is very difficult, yes if the car drives you know that a lot of things must work (engine, transmission, electronics, etc), but if it does not work you have no idea where to look. However, there are some things which you will have very hard time reproducing in this end-to-end test. For example, it will be very hard for you to see if the car will be able to start in the extreme cold of the north pole, or if the engine will not overheat going full throttle up a sand dune in Sahara. I propose we take the engine out and simulate the load on it in a laboratory.

from It is not about writing tests, its about writing stories

In the rest of his writings you'll also find how to structure your code in a way that makes unit testing easy and does not require crazy mockings. I am also convinced that code structured in that way is well decoupled and easy to understand, modify and talk about.

Friday, December 17, 2010

Experiments in Inheritance - a screencast

This is a short screencast I made to replace the video made at my London Perl Workshop presentation. It did not make the list eventually - but I still think it might be interesting: http://warszawa.pm.org/WebNanoInheritance.mpeg. It is my first screencast ever made - please comment.

The main idea presented there is about solving the "give mi an application like this one but ..." problem, illustrated by making a blog engine that inherits from Nblog, but extends it and overrides some of it's elements.

Monday, December 13, 2010

Namespace Matching

The other day I was reading the Dancer Advent Calendar and I finally found the two words description of what WebNano does. WebNano is the minimal addition to PSGI that provides Namespace Matching. Beside easy deployment, which is currently covered by Plack, Namespace Matching is probably the main feature of Catalyst and now with WebNano you can have that without the heavy baggage of the whole of the Catalyst framework. I think it is important because it seems to produce just the right granularity of the controller classes and provides a path for the application growth (without overloading one file with too much stuff).

Sunday, December 05, 2010

WebNano - some incompatible API changes ahead

I tried carefully not to document some things that are likely to change in the closest WebNano releases, but the example code I put in the docs needs to be exact and that means it contains some details I have not yet decided are stable. One of these examples is about overriding the local_dispatch. It used to take the path as a string parameter - now it takes an array - i.e. the path split on the '/' character. The past way was more universal as it let the user programmer to specify how to parse the path - but I think splitting on '/' is such a common usage that it justifies the change. And it is not destructive - so if someone really want's to parse the path in a different way then he can join it back.

This change will be in the next WebNano release.

In the longer perspective I am thinking about being more compliant with the Law of Demeter and building the controllers with the needed model parts in their own attributes, instead of accessing them through app. So for example some code in Nblog would change from

$self->app->schema->resultset( 'Article' )->search
to
$self->article_rs->search

Now this can be done by overriding the handle class method - but maybe it needs something more elegant.

Wednesday, December 01, 2010

WebNano as Catalyst::Tiny

If you have read The Philosophy of WebNano you might think that WebNano is radically different from Catalyst, the more so if you'd compare the size of these projects (sloccount reports over 5000 lines in lib for Catalyst, versus less then 250 for WebNano). But if you compare the code structure between Nblog and the original RavLog project you'll find it very similar. The DBIC schema and form classes were just copied around, you'll see mostly the same controllers with mostly the same methods.

Look for example at Nblog::Controller::Ajax and RavLog::Controller::Ajax - the changes are minimal, mostly just changing sub check_articles : Local to sub check_articles_action and accessing the model from $c->model('DB::Tag')->search to $self->app->schema->resultset( 'Tag')->search - a bit longer perhaps. Sure there are other controllers like: RavLog::Controller::View that I renamed to Nblog::Controller::Article. This renaming is not important - I just did not like a controller called View but there is also some difference in their methods. The RavLog controller uses the Chained Catalyst dispatcher - while in the Nblog one I overrode local_dispatch, and it uses stash to communicate with the template while in Nblog I passe the data directly as a parameter. Still some similarity remains.

WebNano uses some dependencies - so it does not fit into the original Adam's definition of tiny modules (by the way I cannot fin this definition now - maybe this should go to some semi-official place like the p5p wiki?). But the prerequisites are really minimal - and mostly tiny themselves. Maybe in the subject space of web frameworks this should be allowed?