2012 Feed

Back To Basics

OX - 2012-12-12

Round And Round It Goes

At this point, you've had almost 2 weeks worth of in-depth details about the OX framework, including entries Path::Router, Bread::Board::Declare, OX::Request and OX::Response, and Plack, PSGI, and more middleware than you can shake a stick at. After that deep dive into all the components that you can make use of in an OX application, it's a good time to step back and look at the big picture again, and review what I consider to be one of OX's greatest strengths: the way it allows you to develop applications across a wide range of scales, and to iteratively move from one scale to another as the complexity of your application changes over time. Like so-called micro-frameworks, OX allows you to start developing an application as a single simple module -- and then over time, if the complexity of the problem calls for it, you can iteratively evolve your app into a multi-module monster, with a full MVC-oriented architecture (or MVA, or whatever the flavor du jour design pattern is). Because OX applications are really just Moose applications, they can be as simple or as complex as you need.

My Pomodoro Technique Is (Almost) Unstoppable

Let's say you wanted to develop a simple web-based application to help you use the Pomodoro Technique during your daily work. The basic principle of this technique is alternating periods of work (typically 25 or 50 minutes long) with short breaks (usually 5 to 10 minutes). Each cycle is called a "pomodoro", and every three to four pomodoros, you take a longer break (usually 30 minutes). During the course of a single pomodoro, you focus exclusively on finishing a single task, such as implementing a new feature or fixing a bug.

I like the Pomodoro Technique quite a bit, and I have found that on those days when I don't have a lot of external interruptions (meetings, client phone calls, etc.), it's a really good way to balance staying focused on work with making sure I don't completely lose track of time or the overall structure of my day. I can make a rough plan at the beginning of the day -- this many pomodoros on this task, this many on that -- and then I have a rough outline for how my day should go.

The biggest problem I have with my Pomodoro Technique -- aside from those pesky client calls! -- is keeping track of which pomodoro I'm on to know when I should take my longer break. Was that the third or the fourth pomodoro? The fourth or the fifth? I frequently have that longer break set aside as a time to eat lunch, run an errand, or go for a walk or jog, so I want to make sure I take care of those things as well.

PomodorOX To The Rescue

Let's make the simplest possible OX application to track which Pomodoro we're on at any given point. Since this is going to be something I run locally and that typically won't be seen by anybody other than me, it can be as ugly... I mean, as simple and pragmatically efficient, as it needs to be. I spent about one pomodoro on this problem, and what I came up with looks like this:


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 

 

package PomodorOX;
use OX;

use Lingua::EN::Numbers qw/ num2en_ordinal /;

my $goal = 12;
my $done = 0;
my $state = 'initial';

router as {
  route '/' => sub {
    my $ord = num2en_ordinal( $done+1 );

    my $label = ( $state eq 'break' or $state eq 'initial') ?
      "Start $ord pomodoro" : "Finish $ord pomodoro and take a break";

    if ( $state eq 'pomo' ) {
      $state = 'break';
      $done++;
    }
    else { $state = 'pomo' }

    return <<EOHTML;
<p>POMODOROS DONE / PLANNED: $done / $goal
<input type="button" value="$label" onclick="window.location = '/';" /></p>
EOHTML
  };
};

 

This simple module implements a simple pomodoro tracker, which will keep track of how many pomodoros you've completed over the course of the day. As we saw way back in day 1, since the router block returns a valid PSGI application, you can load this module directly with plackup to run this application.

(Note: you can download this application here.)

Evolve Or Die

One could code this simple application in any of a number of Perl web frameworks and it would look essentially the same -- what's the advantage of OX, exactly? The advantage, as I said above, is in the way the OX framework allows you to iteratively evolve an application without huge changes in the application structure. For example, let's say you decided that you wanted to load the goal -- the number of Pomodoros you're trying to do in a day -- from a config file instead of hard-coding it. That might look like this:


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 

 

package PomodorOX;
use OX;
use 5.012;

use Lingua::EN::Numbers qw/ num2en_ordinal /;
use YAML qw/ LoadFile /;

my $config = LoadFile( 'pomodorox.yaml' );
my $goal = $config->{goal} // 12;
my $done = 0;
my $state = 'initial';

router as {
  route '/' => sub {
    my $ord = num2en_ordinal( $done+1 );

    my $label = ( $state eq 'break' or $state eq 'initial') ?
      "Start $ord pomodoro" : "Finish $ord pomodoro and take a break";

    if ( $state eq 'pomo' ) {
      $state = 'break';
      $done++;
    }
    else { $state = 'pomo' }

    return <<EOHTML;
<p>
POMODOROS DONE / PLANNED: $done / $goal
<input type="button" value="$label" onclick="window.location = '/';" />
</p>
EOHTML
  };
};

 

Only lines 6-9 would need to change to add a configuration file. Further, because OX is completely configuration-system agnostic, you don't have to use YAML. You could use Config::General, or XML::Simple, or roll your own PomodorOX::Config module.

Longest Journey, Single Step, You Know The Drill

The point of this article is not that you need to start all your web applications with a single module design. That would be silly. The point is also not that you should use the Pomodoro Technique -- although you may want to give it a shot.

No, the point of this article is that, while OX does build on a number of components, and on some concepts (such as dependency injection and inversion of control) that have a reputation as being somewhat difficult to get ones head around, you don't really have to deal with those concepts to start using OX. You can start making useful web applications using only the simplest parts of Path::Router, and move on up to the capabilities that the Bread::Board::Declare-based service resolution gives you once you get to the point where your application needs it.

So block out a pomodoro or two today, and make a simple OX app. (If you can't think of anything special to do, make PomodorOX suck just a tiny bit less.) Once you've got that app working, add another bit of functionality. When you've gotten it to the point where you really want to refactor that inline action path out of the router block, then you're ready to go back and review the first few days in this calendar, and join #ox and start asking questions.

Happy coding and happy holidays!

Gravatar Image This article contributed by: John SJ Anderson <john.anderson@iinteractive.com>