Results tagged “Perl”

YAPC 2010 in Review

A few days with the JAPHs has reminded me of a few things:

  1. I’m behind. I need to do a better job of keeping up with Perl things.
  2. Perl has a unique culture and community that is both interesting and valuable to what it produces.
  3. I’m so glad that the people I usually hang out with do not use a certain expletive as their favorite adjective.

Okay, so let’s review.

Sunday

I traveled to Columbus, Ohio on Sunday. My travel was mostly uneventful, other than an hour delay in Dallas to replace the brakes on the plane. Because of that, I didn’t get to have dinner with Terri’s cousins, just her uncle. However, I enjoyed a delicious meatloaf and lemonade with Keith at the Cap City Diner (warning the web site plays music). I arrived at The Blackwell that evening, which is apparently named after a professor at OSU who has been convicted of insider trading.

My first impression of Ohio State campus is that they must have had a beautiful football stadium at one time, but now appears to be just a modern monstrosity with a beautiful arch on the end facing The Blackwell. I suppose this stadium will soon be featuring regular visits from our northern neighbors in Nebraska… I’m not an OSU fan, but I hope OSU beats NU every time they play here.

While traveling and late into Sunday evening, I finished up my notes for my first talk.

Monday

I met my colleagues in the lobby and we walked together over to the Ohio Union, where the conference was being held. The Union is knew and was a very nice place to conference, particular one priced at the value that YAPC is—though, my conference registration was paid for by the low-low price of giving two talks, which is great since I was just talking about two subjects I like to talk to others about anyway.

The keynote on Monday was given by Jesse Vincent, who was the Perl5 v12 pumpking, which has been released and is well into it’s maintenance cycle now. For those that may not know, this marks the second major release of Perl in the last 3 years and is part of a new effort to consistently make a major release of the language every year. This is good news for at least a couple reasons.

  1. Perl language developing will stay fresher with new features coming regularly.
  2. It will help dispel the message of the naysayers and show that Perl is Alive.

After that, I went to a couple talks on Catalyst that I didn’t pay much attention to. This had far less to do with the quality of the talks and more to do with me thinking about my talk.

I gave my first talk at 10:00 am on Telecommuting. I will post the audio/video when Krishna gets it online. I may post the slides too, but there’s really not much to show in them. Most of it was me telling a few stories from note cards. I feel like I was a bit dull, but I got some good questions at the end, which is usually a good sign. As I said on Twitter, I hope it was useful.

After breathing a sigh of relief I spent most of the rest of the day in talks and working on a project for work. I attended Util’s talk on Amazon EC2. I learned that EC2 hasn’t changed significantly since I used it. It’s still the same, though there are more instance configuration options, Windows instances, and different storage engines. This is mostly just an extension of what was there when I was last using it a couple years ago.

We then grabbed some lunch from The Flying Pizza, which was cheap and greasy and pretty good.

After lunch, I ended up in Moose for Managers, which wasn’t a stand-out talk in my mind since I can’t remember anything about it. However, I was working on something related to work at the time, so that’s probably just me not paying close enough attention. I stayed in the Grant Street Room to listen to Paul Fenwick’s talk on Awesome things you’ve missed in Perl. Paul is a great speaker and showed a number of things I’ve put on my todo list to investigate.

I ended the regular talks for the day by attending Dave Rolsky’s talk on Fey and Fey::ORM, which I’m mildly curious about since I once tried to write an ORM and because Fey seems like something which could be useful for something at work. By the way, my attempt at an ORM was awful and Dave actually wrote a scathing review of it on CPAN Ratings, which is part of the reason it has been disappeared from CPAN…I think that may have been my first CPAN module. Oh well. No hard feelings.

Finally, there were the lightning talks. They were enjoyable, as usual, but I’m not sure there are any that stand out in my mind from Monday.

After that, my fellow Grant Streeters headed out to dinner. We went to a local, cheap Chinese place, which was pretty decent. I stayed up late working after that, though after all the talks and travel I was pretty spent, so I got done far less than I wanted.

Tuesday

I ended up sleeping in a bit and missed the first round of talks and caught only the last part of Michael Schwern’s talk on the coding cycle. I stayed in the Grant Street room to see Gabor Szabo’s talk on Padre, which I’ve long been interested in, but still haven’t looked at much. If you want to learn Perl, using this editor sounds like the best way to get started.

Then it was lunch again, at Chipotle this time. Mmmm… Chipotle.

I attended scrottie’s talk on running Perl in a cheap distributed computing system (i.e., a pile of cheap computers working together to form a supercomputer of sorts). This was followed by Nick Perez giving a talk on how he’s building apps using POE and Plack.

I moved downstairs to another Schwern talk, this time on perl5i, which is a pretty interesting project. He’s basically taken to pulling in his favorite language extensions and piled them into a single module, perl5i. I’m still thinking about how it works and wondering if I like it or not. I certainly like most of the modules he’s brought in and how it works. I’m just not certain I like the mo and mc meta-accessors… still considering it.

After that talk, I stepped out for a while and worked a bit and chatted with some folks in the lobby of the Union. I met a lot of great folks while here, too many to mention all of them.

Then, I attended the keynote, which was given by Stevan Little. This talk explored the history of Perl and how we got to Modern Perl today. Using some concepts by Larry Wall, he wanted to show how Perl had filled a void that once existed in Unix. That is, it used to be if you wanted manipulexity (lots of deep functionality) you wrote something in C. If you needed something with whipuptitude (built quickly and easily) you used shell script. Perl was an attempt to fill in the difference so you could have both manipulexity and whipuptitude. Modern Perl is the outcome and successful implementation of this.

This is also a good opportunity to explain that while Perl has long had the slogan TMTOWTDI (There’s More Than One Way To Do It) from Larry Wall, Modern Perl makes it longer with TMTOWTDI BSCINABTE. This is pronounced Tim Toady Bicarbonate, which acronymizes, “There’s More Than One Way To Do It But Sometimes Consistency Is Not A Bad Thing Either.” This is an extension to Perl thinking that basically adds a little more consistency to programming (via Moose and related thinking) without actually losing any flexibility. (In fact, Modern Perl is really much more flexible in many ways, it just adds a common foundation that makes that flexibility a little more solid and less re-inventive.)

After this came the second round of lightning talks. There were again several good ones, but I think the talk that outshined them all was the one by Makoto Nozaki titled “How I mastered English with Perl.” It was great. I hope the video of it is posted so I can watch it again.

After this, we had the banquet, where I sat with one of my coworkers, Dieter, some of the folks from Best Practical (Shawn Moore, Kevin Falcone, and Jesse Vincent) and got to meet a couple others, Elliot and Ingy. I had a pretty decent time learning a bit about others, talking with Elliot and Jonathan Rockway in the food line, and made a smallish bid on some coasters during the auction. Pathetic, I know, but I did by a new Perl T-shirt since my Perl polo I bought at OSCON is starting to wear.

After that, I went with some folks and ended up talking about work with my coworkers at a local bar before heading back to my room where I stayed up late inventing a new talk to replace the one I wasn’t able to get together in time.

Wednesday

I started the morning by attending another Schwern talk on gitPAN, which is a really cool way of mining information about CPAN using github. This was followed by a talk by Tatsuhiko Miyagawa on cpanminus, which I had only heard rumors of up until this point. Now that I’ve tried it out, I’m not sure why I haven’t been using it for months now. It’s a very nice (simple!) CPAN client that handles most of what you need when you just want to install a module to try it out.

I then gave my second and final talk on Form::Factory, which showed a bit on how to extend Moose and how I like to build forms, but I don’t think it’s earth shattering. I would like it to be, but my time to hack is constrained by so many things.

I followed that with mst’s talk on The Troll, the God, and the Mountain, which was a very unusual introduction to DBIx::Data::Store. The punchline is that the Troll, Thog and his friend Al, are renamed and made great by the god v10 (“Voton,” i.e., Perl 8 v10) to become “Orthog-an-Al Persisten-T roles.” That’s about all I remember, to be honest. I’ve been hearing a few rumors about this project via Rob Kinyon (I think), though, so I’m keeping an eye open for when it hits CPAN.

I had one more lunch at YAPC, with a bunch of folks I didn’t know and Rob. I confess to have forgotten all names at this lunch, but they were good company for lunch.

Next, I attended Cool Perl 6 today by Patrick Michaud, who is the lead on Rakudo, which is the engine for Perl 6. I’m really thinking Perl 6 should be renamed to something else because it’s like Perl, but it’s not Perl. I like to watch these talks mostly for fun, though, things are getting to the point now that you can write Perl 6 applications, which is tempting to try.

I then attended a really excellent talk on autodie, titled “The Art of Klingon Programming” by Paul Fenwick. The talk featured Paul in a TNG uniform talking about his time as an exchange officer in the Klingon empire where he was testing the new universal translator. The joke is this. If you’ve programmed very much Perl, you know a common idiom is to write “open or die.” The reason is that if the file doesn’t open it returns a false value, so the short circuit “or” operator allows you to skip the die on success or run the die on failure. This is a good way to ask for blood wine in Klingon, since trying to ask nicely won’t get you any. The autodie module comes along to make this kind of talk automatic (making open die without the “or die” on the end).

Prior to the final keynote by mst, I attended two more Moose talks, one by doy and the other by perigrin. Both had way more information than I was really able to consume and the major thing that I took away was that I need to look into the new declarative syntax and immerse myself more deeply into the Moose type system, which I’ve really barely touched.

The final keynote was given by mst, which was another summary of the history of Perl as well as a general summary of some of the good things that have happened in the world of Perl in the past year.

After that, I went over to the Blue Nile Ethiopian Restaurant with the other speakers (and hangers on) and experienced my first taste of Ethiopian food and had one more social event. I got to speak a bit with chromatic, whom had edited the articles O’Reilly published to OnLamp. I got to chat with Ricardo Signes, Dave Rolsky, Rob’s wife, Randall Schwartz, and several others. It was a good time.

Finally, it was time to pack and head home.

In Summary

Perl has a really interesting culture. Between the libraries on CPAN, the dedication of many developers to the language and the community, and the way the leaders in the community interact with it, Perl has a lot going for it. It almost seems like there is a bit of religious fervor to it, though, that’s partially just the concentration of people getting together to talk about Perl. Most of these folks work in other languages too and have important concerns outside of Perl.

On my list of things I need to look into from the conference:

  • Perlbrew: A nice way of installing Perl VMs for development and testing.
  • local::lib: A nice way of locating and using CPAN modules installed to your home directory.
  • cpanminus: A tool that simplifies installing modules from CPAN.
  • Bread::Board: A framework for inversion of control, which is something I want to do better with in Form::Factory
  • CPAN Explorer: A visualization of CPAN.
  • Reflex: A new syntax for doing POE-like things with Moose.

There are others, but I don’t want the list to get too long.

Anyway, that’s my summary of everything I have to say about YAPC::NA 2010. Lord willing, I hope to attend again.

Cheers.

Help! Help! I need help!

I’m giving a talk at YAPC 2010 on telecommuting as a software developer. For the talk to be successful, I’m going to need more than just my own experience to pull from. If you are a telecommuter and have a moment, I would appreciate your help in filling out this survey.

The goal of the talk is two-fold:

  1. I want to explain the benefits and risks of telecommuting as a Perl developer.
  2. I want to provide some practical tips to help fellow telecommuters.

I want the format to be oriented towards telling a number of stories about telecommuters with practical advice interspersed.

Perl Telecommute Survey

Recently, I’ve started backing away from Jifty as my web framework of favor. There are a few reasons for this, but mostly it’s related to performance. Jifty is includes everything, Ajax, dispatch, ORM, Comet/PubSub, REST, forms, HTML, templating, and a pony (probably a kitchen sink too). Basically, with Jifty you don’t need to spend very much time working on building up your own utilities or framework upon framework to fit your style or needs. Jifty hands you a style as well, one that I mostly like.

However, the cost to performance on my Qublog project was too much. It was easier for me to port it to Catalyst sans-Ajax than it was to try and correct the performance issues. In addition, I no longer use Jifty for work, wanted to use features of DBIx::Class, Moose, etc. I’m not trying to bag on Jifty here, just explain why I’m moving away from it general. I very well may find a use for it for something in the future.

There is, however, a major feature of Jifty I miss after having moved to Catalyst. Jifty has a collection of classes for encapsulating form rendering and processing. At the center of this is the action class, which is really a glorified functor, but with all the accoutrement required to render an HTML form and to clean up, verify, and process submission. I like this. I like this a lot. I decided to use the flexibility afforded by Moose with an implementation of something like these action classes to create a new form handling system. Over my Thanksgiving vacation, I was able to build up what has become Form::Factory.

An Example

Okay, I thought about showing you the process I worked through to get here, but you probably want to see it in action first. I’ll work backwards from there.

In order to use Form::Factory, you must first define an action class. Here’s a simple login action you might use to present a login form to your users in a web application:

package MyApp::Action::Login;
use Form::Factory::Processor;

has_control login_name => (
    control => 'text',
    features => {
        required => 1,
        trim => 1,
        length => {
            minimum => 3,
            maximum => 20,
        },
        match_regex => {
            regex => qr{.@.}, # really naive check for email address-ish thing
            message => qw{your %s should be an email address},
        },
    },
);

has_control password => (
    control => 'password',
    features => {
        required => 1,
        trim => 1,
    },
);

has c => (
    is => 'ro',
    isa => 'MyApp',
    required => 1,
);

sub run {
    my $self = shift;

    if ($self->c->authenticate({ name => $self->login_name, password => $self->password })) {
        $self->result->success("welcome back,  @{[$self->login_name]}!");
    }
    else {
        $self->result->failure('the login name and password you entered is wrong');
    }
}

The has_control calls establish the inputs expected for our login action and tell the action what features those controls have. For example, the required features will result in a form that reports an error for that control when no value is given during a submission.

The run method here actually performs the action. (For this example, I’m using something Catalyst-ish, but this could just as easily be used with CGI, CGI::Application, Plack, Jifty, or whatever you prefer.)

To use the login action in our web application, we’ll now need to send the form to the user. Here’s a Template::Declare template that should work:

template 'user/login' => sub {
    my ($self, $c) = @_;

    page_wrapper {
        form { { action is 'user/check_login', method is 'POST' }
            my $interface = Form::Factory->new_interface(HTML => {
                renderer => sub { outs_raw(@_) },
            });
            my $action = $interface->new_action('MyApp::Action::Login', { c => $c });
            $action->unstash('login');
            $action->render;
            $action->clear_messages;
            $action->stash('login');
            $action->render_control(button => { name => 'login' });
        };
    };
};

That would render an HTML form that the user can then fill in and submit. The new_interface call creates an instance of an interface class. These are responsible for connecting an object to the user interface. In this case, it’s an HTML form.

The new_action call then creates an instance of the action class associated with our interface class. Note that we can pass a hashref of arguments that will be passed to the constructor.

The unstash and stash calls are handy for remembering certain things about the form. This includes any error or success messages associated with processing the form. For example, if the user entered their login name, but the incorrect password. The processing bit (which we’ll see in a moment) would stash the error from trying to authenticate and would also stash the login name itself (but not the password since passwords controls don’t ask to stash their value). Then, when the form draws again, teh error message will be shown and the login name box will come prefilled with the previous entry.

The clear_messages call clears the messages from the action so that we can stash a clean slate for the action (we don’t want to see a message we already displayed again).

The render method renders all the controls associated with the action. (By passing the controls option you can output only a subset if you wish.) The render_control is used to output a button that is not directly associated with the action (in this case we just use it to get the user to send the form back to us).

Once the user clicks on our “Login” button, we’ll then want to process the input. That looks something like this:

sub check_user_login :Path('user/check_login') :Args(0) {
    my ($self, $c) = @_;

    my $interface = Form::Factory->new_interface('HTML');
    my $action = $interface->new_action('MyApp::Action::Login', { c => $c });
    $action->unstash('login');

    $action->consume_and_clean_and_check_and_process(
        request => $c->request->params,
    );

    if ($action->is_valid and $action->is_success) {
        $c->response->redirect('/index');
    }
    else {
        $action->stash('login');
        $c->response->redirect('/user/login');
    }
}

We get the interface and action objects same as before. We unstash the saved information again. Then, we do that long method, which is a shortcut for saying:

$action->consume( request => $c->request->params );
$action->clean;
$action->check;
$action->process;

The consume method takes the input and applies that to each control object.

The clean method then cleans up the values given to each control. In this case, for example, the login_name will have whitespace trimmed from the beginning and end since it uses the trim feature.

The check method then validates the inputs to determine whether or not we can reasonably expect the user’s input to have a chance at working. Here’s where most of the features added above will do their work. If the user does not enter anything for the username, the required feature will cause the control to be set as invalid.

Then, the process method will cause the action to process. Actually, the process method itself first checks to see if the input is valid and does nothing if it is not. If it is valid, it will copy the values from the control objects into the action attributes and run the run method defined on the action.

Finally, we can check the success or failure of the action and react accordingly. That’s how Form::Factory works in a nutshell.

Goals

Now that you’ve seen an example, here’s what I want to achieve in a nutshell:

  1. Actions should be well-structured, but very simple to build.
  2. Actions are tied to the user interface by controls, which are easy to extend.
  3. Common features of actions should be simple to define and associate with actions.
  4. User interfaces should be easy to build for hosting actions.

Actions are Well-Structured, Simple

Actions are just functors, function objects. At the center of each is a run method responsible for taking some action. To get there, however, you need input and after you get there you need output. Form::Factory uses Moose attributes to specify what input the action takes. Each has_control builds an attribute onto the action, but also associates more information about how it interacts with the user.

The output is a little less formally specified at this point, but comes out through a result object. The result object is a list of messages associated with the action along with some status information. It can also return a hash of other information for more general output. However, I’m assuming that most of the output of the action is the side-effects the action performs.

When an action is run, it goes through four basic phases to process:

  1. Consume. The user input is delivered to each control associated with each attribute on the action.
  2. Clean. The input in each control is filtered and corrected, allowing whitespace to be removed, numbers to be reformatted, etc.
  3. Check. The input of each control is validated and any errors discovered are reported. Processing stops here if there are errors.
  4. Process. The input in each control is copied into the action attributes directly and the action is run.

In addition to the features attached to the controls, you can specify general subroutines which will run during these phases. For example, if you have a form for changing a password, you might want a check that looks like this:

has_checker check_that_passwords_match => sub {
    my $self = shift;
    my $new_password = $self->controls->{new_password}->current_value;
    my $confirm_password = $self->controls->{confirm_password}->current_value;

    if ($new_password ne $confirm_password) {
        $self->result->is_valid(0);
        $self->result->error('the New Password and Confirm Passwords do not match');
    }
};

This allows you action’s run method to focus on the task it performs and nicely segments off all the checks. You can also logically group your checks and filters so that they are separate from each other. This makes it easier to subclass your actions or compose them from roles.

Controls are the Bridge

An attribute added to your action with has_control has a control object associated with it. This control does most of the work until right before processing. The control receives the initial input, the cleaned input, and is where the value sits when checked. It is not until it is checked that the value enters the attribute instance slot.

Without the control in place, i.e., if we assigned to the attribute directly, Moose would object to the input before we have a chance to do anything. I want to avoid exceptions in this case as well because input validation failures are not exceptional, they’re expected. We need a way to easily send back notes the user about corrections needed and would like to avoid spewing call stacks unnecessarily.

Controls also suggest how the user interface object should present them to the user. An interface is not bound to use these suggestion in exactly the same way as its peers. For example, a text control in HTML might just be a text input box while in a CLI interface might be presented as a command-line option that takes an argument. A check box, on the other hand, will be a check box input in HTML, but would be an option that takes no arguments in a CLI (it’s presence suggesting “on” and it’s absence suggesting “off”).

Features Modify Actions

A common feature of form handling is filtering and input verification. In Jifty these were called canonicalization and validation. Horrible. I’ve called them cleaning and checking. In general, though, the cleaning and checking you want to do is extremely repetitive. On almost everything I want to trim the whitespace and verify that something that is required is present. I often want to check input length for something too long or too short. Sometimes I want to check that email addresses or phone numbers are sane, etc. In Form::Factory, all of these are called “features.”

A feature is a generic object that modifies an action. These can be anything from a feature that is just used to flag the role for some reason to features that actually modify the structure and processing of the form. Features can also be attached to particular controls to clean or check an individual control’s input.

Interfaces Talk to the User

And interfaces are probably what make Form::Factory most unique. An interface looks at the controls for an object and presents them somehow to the user. Currently, I’ve written an HTML interface and a CLI interface. The HTML interface presents them using the matching HTML form controls. The CLI interface presents them as a usage snippet describing the command-line options the action accepts. You can define a single action class and use that action to define a web form or a command-line interface.

I plan to add a REST interface as well, which will be a variation of the HTML interface. Other interfaces I’ve considered (but have no plans for at this time) could include things like a Wx GUI, a PDF interface that builds a PDF with form fields and then consumes FDF documents created from that, an XForms interface, a XUL interface, or a curses interface.

Okay, so that’s my current contribution to the forms parsing arena. I’m still working the kinks out, so be careful if you give Form::Factory a try. Things will change. Otherwise, I’d love some feedback and help ironing out some of the wrinkles.

Cheers.

Perl is not going away

I’ve been taking DDJ for a couple years now. It’s cheap and occasionally has something interesting in it, but it’s been less interesting than I remember it being when I read it in college. I’ve been much more enamored with the Communciations of the ACM. Today, I received my issue and there’s an interview with Paul Jansen of TIOBE Software. In the article, he’s quoted saying:

Another language that has had its day is Perl. It was once the standard language for every system administrator and build manager, but now everyone has been waiting on a new major release for more than seven years. That is considered far too long.

While I am biased, I have to admit that I disagree pretty strongly with Jansen’s assessment. First, let me go into the problems with how he came to this conclusion and then explain why I think I’m justified trusting that Perl is in it for the long haul despite my bias that would have me think so anyway.

I want to first evaluate the way Jansen has collected the data he’s used to make this statement. TIOBE puts together what they call the TIOBE Index. This is a rating of the popularity of various programming languages. The TIOBE web site claims, “The ratings are based on the number of skilled engineers world-wide, courses and third party vendors.” How do they measure this? By performing a search for:

+"<language> programming"

on 5 popular search engines, including: Google, Google Blogs, MSN, Yahoo!, and YouTube. That’s it.

What they are measuring is not actual popularity, but the amount of hype surrounding each one. Not only are they measuring hype, but only hype that discusses “programming”. What if everyone prefers to say “programming Perl is fun!” That wouldn’t get picked up by the search they use. What about “Perl scripting”? Nope. Missed. (Here I should point out that Andy Lester appears to have been on to something when he gave his lightning talk about Perl programs versus scripts at OSCON last year.) In essence, this is, if they’re disclosing the complete metric, incomplete. It’s a shortcut that might be 90% right or 50% right. This is just poor statistics.

The second aspect of Jansen’s comments I take issue with is the statement that there has not been a major release in seven years. That’s not strictly true. Perl 5.10 has just been released and it includes new features like the new smart match operator. Beyond that, there has been some very active development on a closely related project, Parrot, and language development toward a huge milestone, Perl 6. Furthermore, where Perl truly shines is in all the development on CPAN. CPAN is getting large and complex enough now that we’re having to rethink how it works just so we can find anything on it. This is a good problem to have.

This comment by Jansen does, however, serve to indicate a certain perception gap caused by the long wait for Perl 6. It’s even been considered that the name of Perl 6 is harmful to Perl 5. This has been discussed out by others for some time.

In my opinion, Jansen is on shaky ground with his claims and probably only because he’s not well informed by anything but his own metrics. I should think that he’d at least research the trends and issues facing the top 10 languages listed by his survey as to provide some better justification for it’s accuracy.

As for the reasons I still have warm and fuzzy feelings toward Perl’s future, I can list them off rather easily.

  1. I am participating in a number of growing projects that depend on Perl’s future. Jifty and rethinking-cpan are just a couple I’m involved in. I can point you to several other vital projects that I use or am familiar with.
  2. I know of several companies actively pursuing Perl to develop core projects and continuing to train developers. This includes imdb.com, Socialtext, Best Practical, Six Apart, and several others.
  3. Recently, Google launched Google App Engine. This tool provides services to Python developers as part of the initial release. The top most voted for issues are first to add support for Ruby and second to add support for Perl, as of this writing.
  4. There’s an average of 50 new and updated modules being posted to CPAN every day. That’s not a small number.

I can probably come up with more, but now it’s getting late, so I’d better end this thing. If Perl is going to die, it’s got some years left before it happens. I think there will be enough activity to keep it going and increasing during those years rather than dying.

Cheers.

Andy Lester has issued an interesting challenge regarding CPAN. First, I have to say that CPAN is probably at least one-third of the reason I love Perl. Having a centralized, search-able, browse-able, and documentation-oriented repository of modules makes development so much easier than any other alternative I'm familiar with. In addition to all that, it has reviews, forums, a bug tracker, test result summaries, etc. That said, it is far from perfect.

There are two main complaints that I get. The first is from friends who are systems administrators. They often despise CPAN because they don't care if it helps developers easy locate and include modules. All they see is that to install some application, they have to install 15 modules, which installs another 22 dependencies for those, and then another 18 for those, and then another 12 for those, and then another 5 for those and then finally 2 more. This can take hours to build and install all of them. This is just a hassle for them.

From a developer perspective, I also have the problem that Andy highlights: which effing modules solves my problem? For example, if I want to build Subversion/CVS/Git style commands with sub-commands I could use App::CLI by clkao or App::Cmd by Ricardo Signes. Which one is better for my problem space? Both are by smart developers and both are well put together, but they are completely different implementations for a similar problem. This is something that CPAN won't help you with very much. Andy's example of XML is even more complicated.

There are other problems as well. Here are some ideas I've had that could be implemented in individual chunks that could help.
  • Wikifying the documentation. This is an idea I've thought some about and even worked on designing an implementation for a bit over my Christmas break. This is basically about allowing visitors to contribute POD to a module on CPAN using a wiki-ish interface. This could improve the documentation. The challenge is that CPAN documentation is generated out of the POD stored in modules themselves. There needs some way to make sure that the POD updates made on the Wiki site can get back into the modules easily. I developed what I think would be a working solution to that problem, but requires the author to pay attention to the wiki and make sure to download the patches. Build tools could help automate this process, though.
  • Dependency mapping to cluster modules. Every module contributes a metadata file that should list the dependencies required to run that module. I can think of several useful things we can do here on a large scale. We can use that to suggest which modules are more popular or better based upon how many modules depend upon it. We can use this to indicate (or estimate) how many overall dependencies a particular module has, i.e., you will need to install 184 module dependencies to use this module. We can also tie this dependency information into other features like reviews and ratings to generate other helpful statistics and heuristics.
  • Incorporating use statistics. Sites like ohloh, or iusethis have a good idea in how they can rate content. It's not a perfect system, but letting a person just click a counter that says, "this is good" or "I like this" provides a very simple mechanism to rate a module. In addition, it allows you to gather statistics grouping modules again in another way.
None of this is a new idea. None of these are really very innovative, but I think they would be steps in the right direction toward making CPAN work better and better. If we can incorporate additional metrics into how the search works, adding tagging, or who knows what else along the way would go a long way.

I wonder if we could expose the CPAN services currently available in some sort of unified web service that would allow developers to try and enhance and experiment too. This could make it so that CPAN grows in new ways without a lot of overhead to get TPFs attention or what-not.

I don't know. More ideas...

Cheers.

I'm currently experimenting with some stuff related to using JavaScript on the server and the client. The results I'm getting are somewhat mixed. The idea I had was to see about letting someone customize some aspects of an application I'm developing that is intended to help you live more healthy. Basically, based upon the statistics of a food or other parts of the application, you could create custom metrics to measure your success or failure according to your particular preferences. (Some people monitor carbs, some monitor Weight Watcher points, others are interested in fat and protein, etc.)

I've successfully added tools that will allow you to add your custom metrics to the system using your own JavaScript snippet. This snippet is passed a object representing the food item (and eventually to include other information). I can then calculate your metric based upon the current food your viewing and your code.

This calculation is performed on the server side using Mozilla Spidermonkey
and the JavaScript
module on CPAN. On the server, this ends up looking something like this:

use JavaScript;
my $runtime = JavaScript::Runtime->new;
my $context = $runtime->create_context;
$context->eval_file('benchmark.js'); # base API library

# do some other setup of the objects I need in __tmp.food

$context->eval(
q/function evalIndicator(food) {/
.$user_calculation # this variable contains code from the end-user
.q/}/
);
$result = $context->eval(q/evalIndicator(__tmp.food)/);

I've added a little more in there for error handling and such, but that's the core of how I handle the work on the server. The really nice thing here is that the user's JavaScript can't really do much bad other than a denial of service by looping or recursing internally. The server-side JavaScript doesn't include any BOM objects that could be used to do terrible things like steal user information, etc. Furthermore, if I run this code as a separate process that communicates back to the server, I can easily wipe it out if it takes longer than a few seconds to work.

Then, using a combination of Dean Edward's sandbox
and some custom hacking of my own, I can then provide on-the-fly updates from the client using most of the same JavaScript code. This allows the JavaScript to run in a relatively safe container within a hidden IFRAME.

On the client, I've implemented the sandbox in this form. I've left out some of the error handling and other details for simplicity:

// Dean Edward's sandbox in OO form:
function Sandbox(preloads) {
  this.iframe = document.createElement("iframe");
  this.iframe.style.display = "none";
  document.body.appendChild(this.iframe);

this.frame = frames{eval:function(s){return eval(s)}};"+
"top=opener=parent=null"+ // cut off access back to the parent
"<\/script>"
);
this.frame.document.close(); // stop the throbbing
}

Sandbox.prototype.eval = function(code) {
var sandboxObject = Sandbox.functions[this.serialNumber

;
return sandboxObject.eval(code);
}

Sandbox.prototype.close = function() {
document.body.removeChild(this.iframe);
Sandbox.functions[this.serialNumber] = null;

this.frame = null;
this.iframe = null;
this.serialNumber = null;
}

Sandbox.serialNumber = 0;
Sandbox.functions = new Array();

Now that I have the sandbox to run things in, I need to setup a similar environment as I use on the server. My initial implementation embeds the user's code as a special attribute in the middle of the page, but it could be special block in the header or an Ajax request once to fetch the code string into a variable just after load, etc.

// This code runs onload, to make sure benchmark.js is loaded completely
var sandbox = new Sandbox(['benchmark.js']); // base API library

// When the user changes a value inthe page, the calculation can be made again on the fly...
var result = sandbox.eval(
""

// do some other setup of the objects I need in __tmp.food

+ "function evalIndicator(food) {"
+ user_calculation // this variable contains code from the end-user
+ "}"
+ "evalIndicator(__tmp.food)"
);

Again, I've omitted some of the other details to keep this article at a manageable length. That's the gist of how I run this on the client.

Now, after I've done the work, I probably am going to drop the client-side effort and provide updates by contacting the server using Ajax-ish requests. Why? Well, I can control the server-side environment much more closely by running the code in a separate process that I can kill off if it runs away. If someone's code accidentally (or intentional) tries to do something malicious on the client, I get the blame. The browser is a much less controllable environment. They could fire off requests passing information regarding the end user off to an unknown third party or compromise something even worse if I'm not very careful. I'd have to do a very thorough job of stripping the sandbox area completely. Even then, I don't know if I can actually protect the user from a malicious attacker since there are so many unknowns regarding browser implementations. I'd need to do a lot more studying before I'd be willing to run untrusted code this way for sure.

On the other hand, this trick might work swimmingly in an environment where I trusted all the code being executed in both boxes. I'd certainly be willing to do this on a project at some point to provide calculations on both server and client using the same embedded code, which is why I'm writing the article for others. Anyway, this has been an interesting adventure in JavaScript.

Cheers.

OSCON 2007 In Review

Okay, here's my take on OSCON 2007. I had a great time. It was good to be surrounded by professionals who do and care about many of the same things I do. Most notably: software development and Open Source. I met several folks and, being my first real Open Source event, I saw quite a few famous people whom I'd only seen in pictures or Revolution OS.

Tuesday: Travel

Cool clouds on the way to Portland

I skipped the tutorials (though, not completely willingly). That was mostly because I didn't want to be away from my wife and 7 month old son for longer than 4 days. I traveled to Portland direct from Manhattan, Kansas. Unfortunately, my flight arrangements were such that I was on three flights rather than just two. (My flights were not made by me.) I do thoroughly enjoy the first 40 minute jump from Manhattan to Kansas City on a Beechcraft B1900 turboprop. I also like to laugh at the n00bs on the plane that are a little nervous about riding a plane only holding 16 passengers. "Oh my, it still has propellers." N00bs.

My trip from Manhattan to Kansas City to Phoenix to Portland was pretty much uneventful. I caught the Trimax into downtown and walked over and checked into the hotel. I then met Lance for some Chipotle and headed over to the Doubletree where we met up with Seth and hung out in the bar for a bit. Then back to sleep a bit.

Wednesday: Sessions Day 1

The first keynotes of the day weren't very interesting. I now know what Mark Shuttleworth and Tim O'Reilly look like, but the only talk I found very interesting was the one on Transactional Memory and that for technical reasons I won't elaborate here. As with most conferences, they always try to pack as much of the best stuff into the first day of sessions since that's the day most people stay for. There were at least 3 sessions during each period I wanted to attend.

Keep Your Sense Of Humor hackable Tux robots

After the keynotes I hit the expo hall and started picking up free T-shirts, pens, and other swag. Here I met with James Turner, who's been my editor for a couple of my OnLamp.com articles. He was showing off his work on his comic at the Watering Hole. I also saw Mark Tiemann, current OSI President and founder of Cygnus, here, whom I recognized from Revolution OS, handing out OSI T-Shirts in exchange for donations.

For my first sessions I went to How to Herd Cats and Influence People with Jono Bacon of Canonical. The basic recommendation of the session is that if you want a successful community make it very easy to participate. Period. There was a comparison with McDonald's and how they've made it so easy for morons to make burgers and that's the secret to their success. In Open Source, we should learn to do the same.

Spam on one of the whiteboards outside the Expo Hall

The second session I attended was Care and Feeding of Large Open Source Applications by Perrin Harkins, which was basically a talk on the project management tools available for Perl development. It was largely a review of what I already knew on the subject, but he did provide some good suggestions that I hadn't really worked with before, such as using Test::Class.

I ate lunch with Seth and a couple other attendees and then moved on to the afternoon sessions. I nearly went to Beautiful and Unique Snowflakes: Cooking with Catalyst with Matt Trout, whom I've chatted with on IRC but missed shaking hands with at OSCON, unfortunately. However, I saw that his session was introductory and I've already built Catalyst applications (including a blog I used on this site briefly), so it probably wouldn't have been the best session to attend. Instead, I went on to Who Am I? The Age of the Digital Identity by Robert Richards, which was about OpenID and InfoCard. His talk was interesting, particularly since I'm writing an SSO application, CAS+, but I had a hard time following the talk. I hope to implement OpenID in my application, but I can't just yet (or at least, not as the primary login mechanism) as our clients aren't quite ready for it.

After this I went to the Perl 6 Update with Larry Wall, which was interesting as ever. One reason I got into Perl 5 was because of what I'd read about Perl 6. I decided on Perl as my language of preference during my first year as a grad student. I had hacked around in Perl before while working on Anomy Mail tools when I was with Network Resource Group, but I didn't take any particular liking or disliking to the language at that time. As I started my Masters Degree I was trying to decide which language I liked for building web applications since I already new I didn't like Java and while I liked C++, it's not considered an ideal language for web development. I tried out Python and then taught myself some better Perl and felt an affinity to Perl immediately. I can think Perl. I read the first couple Apocalypses and was sold when I found out what Perl 6 would (eventually) be. Larry Wall and the Perl 6 language team continue to impress with more good ideas and the elimination of more bad ideas.

Ubuntu Hair Guy at the OpenSolaris Party

After the Perl 6 Update, I went to the Programming with SQLite talk by Michael Owens with Lance and Seth. The main thing I learned from this talk is that SQLite isn't like other SQL databases and requires a little more manual intervention to make things work just the way you want, which can be seen as an advantage or disadvantage. That is, if you want to use SQLite efficiently, take your locking seriously.

Lastly, I went to Myths of Innovation by Scott Berkun and then promptly went down to the book store and bought his book. I don't agree with everything in the book (particularly the veiled hostility toward spirituality), but it is a good book overall.

Lance, Sterling, and Seth

At the end of the day, I took Lance and Seth out to the Rock Bottom Brewery where they had a couple pints and a microbrew sampler. I even drank a couple of the samples and enjoyed them as much as anyone who doesn't drink can. We then headed over to the OpenSolaris party at the Doubletree and I met Donnie, who's a PhD student at OSU, one of the top guys at Gentoo Linux, and a friend of Lance's. After chatting at the party for awhile, Lance and I headed back to the Red Lion to end another day.

Thursday: Session Day 2

The Thursday keynotes were very interesting. The keynote by Robin Hansen on Bias was simply depressing, but basically stated a fundamental Christian belief, people have a veil pulled over their eyes and refuse to believe truth when it whacks them in the face. Of course, he didn't make any spiritual remarks and my statements would be construed as my own biases in his view. He also made some good points that the key to discouraging bias in the work place is to use competition or even gambling as a mechanism for encouraging truthful predictions of project timelines and such.

Bill Hilf of Microsoft announced that they were sending their Shared Source licenses to the OSI for approval, which got applause. I don't really remember anything else about his talk. He was followed by Rick Falkvinge of the Swedish Pirate Party, which is a political party in Sweden based on the single issue of IP rights. He made some very good arguments about why copyrights are being abused to harm consumers and individual liberties while working to aid corporate and governmental power. His platform is very interesting and I've added Sweden to the places I'd like to visit someday.

The best talk of the morning, though, was Steven Yegge's talk about marketing and branding. He works for Google and was basically saying that OSI needs to remember to be focused on branding. Our brand is very important and the brands of individual products and even developers help us market our products to the wide world. He was very entertaining as well, especially since I think he was probably best representation of the audience that we saw give a keynote. He was one of us and I think he was persuasive only because of that. If a marketing guy had stood up there and said the same thing, he probably would have been written off in that crowd.

One of the One Laptop Per Child laptops

Linux Lightning Talk

After hitting the Expo Hall again for yet more free stuff, I went to the morning Lightning Talks. The talks I noted most were the talk by Donnie on the state of Gentoo and the talk on the current state of Linux, which is mostly funny because the speaker (whose name has escaped me) and his daughter give the talk together. He reads off every patch and improvement made in the last year and she holds up signs summarizing things and then mocking him and penguins toward the end. The most important statistic: Linux receives an average of 3.8 patches per hour all year long.

After lunch, I did want to go to Sam Vilain's Next Generation Version Control systems to learn more about GIT, but I decided to go shopping with Seth instead to pick something up to bring home. I ended up with a shadowbox frame with the cow jumping over the moon for Gabe's room.

When we got back, I went to straight over to Jesse Vincent's talk on Domain Specific Languages, which is interesting talk for me since it was about software I used regularly. It's also interesting because he was discussing work he and others have been doing on Jifty to create mini-languages in pure Perl. The declarative language used by Jifty to create models, action definitions, dispatchers, templates, and (coming soon) web application tests. All of these are written using pure Perl, but it doesn't look like traditional Perl because of how he's stretched the syntax a little bit. I like the ideas a lot and I've always been a fan of DSL's (I did write one for my multi-agent system for my MS a while back). This was first opportunity to do more than just shake Jesse's hand as we hadn't met but over IRC previously. I also stood by and watch Jesse, Larry Wall, and Matt Trout discuss some backport issues from Perl 6 to Perl 5, which was interesting and a little amusing.

Perl in a Nutshell to a tune by Bare Naked Ladies

Afterward, I went back to the Expo Hall to hang out with the OSL guys for a bit before the evening sessions. In the evening sessions, I went to the Perl Lightning talks. Andy Lester gave his talk on ack (and alternative to grep) and his assertion that we should call Perl work "programs" rather than "scripts" (which got cat-called by Larry Wall). There was also a rendition of a song by Bare Naked Ladies with new lyrics, Perl in a Nutshell. After the lightning talks, I went to the rest room and met Chromatic (another of my OnLamp editors) on the way out and chatting with him on the way back to where Larry was going to give the State of the Onion. At one point, I had both him and Jesse in front of me so I suggested that we needed a Jifty book. Perhaps we will someday soon. I also got to meet a few of Jesse's "minions" and others here, though I confess that my brain has blurred all the names other than Kevin Falcone.

Larry Wall delivering the State of the Onion

Outside we waited for the Perl Foundation auction to end while everyone made fun of the proceedings inside. However, we were shortly inside and listening to Larry Wall deliver the State of the Onion address, which is something I'd been looking forward to. Larry gave a summary of his history with language and reasserted his view that programming is hard and scripting is easy, so he strongly disagreed with Andy Lester's statement about what we should call Perl application components. He went on to discuss all the different areas where a scripting language can vary: strong typing or weak typing, early binding or late binding, etc. He also showed why he thinks Perl 6 is going to win in the end because Perl 6 isn't so much a new programming language, but the root of a family of programming languages, which played nicely into Jesse's earlier talk about DSLs.

After this, I dropped my stuff off at the hotel and hopped on the train to get over to the Thirsty Lion to attend the Open Source Lab party, sponsored by Jive. We chatted some and then went to the Irish Pub across the street to get some dinner. Lance needed to get back to Corvallis so he checked out and headed home and I spend the evening in the hotel room half-working and half-relaxing.

Friday: Session Day 3

Unfortunately, the last day had come. I wasn't really ready for it to be done. But it was. The keynotes today were certainly the funniest and most memorable of all. Philip Rosedale of Linden Labs gave a talk about Second Life. The most interesting thing about his talk was that Linden Labs does all their meetings in Second Life, which I think would be cool if they had better tools for collaboration that were easier to get to, but with everything going Open Source, perhaps they will.

Jimmy Wales of Wikipedia fame gave the second talk about Wikia which is the "Wiki to End All Wikis" (or he would like it to be) and also about his hope to provide a true Open Source search engine where everything from the algorithms to the data is all open. Which is a good idea, if it can get enough support to work.

Then came the "Keynote Resignation" of Simon Wardley where it was announced that Fotango (though he didn't use the company name) has refused to let it's subsidiary Zimki Open Source it's web development platform, which Wardley was to announce during his keynote. Too bad. It looked interesting and I'm guessing that if they'd Open Sourced it Zimki could have had a chance at becoming a bigger player, now they will be relegated to the same obscurity as the other hosted frameworks. However, his replacement talk on IT Commidization was very funny, though I have no recollection of what points he made other than he likes ducks.

Open Source therapy by the conference MC, Nat Torkington, was basically just an attempt to tell us all to get along with one another. Which I certainly agree with. I may mock Python, Ruby, Java, and PHP every now and then, but I don't mock those that use them (unless they really are worth mocking for other reasons). Anyway, there are certainly lessons that Perl can learn from each. PHP, for example, teaches that ease of deployment can make all the difference in the world to popularity. It also reminds of how bad things get if a language doesn't provide namespaces.

Pimp My Garage by James Larrson is easily the most humorous of all the talks. I hope he posts his videos online, but he basically like to take household junk and revamp it so that it's either funnier or more dangerous. He had some excellent visuals and I think he has a thing for tall leather boots.

For the last two sessions, I thought about going to Hack Your Manager, but ended up in Adventures in Copyright Reform with Karl Fogel, which was somewhat enlightening as to how the RIAA and MPAA are trying to restrict civil liberties in order to help their clients (record companies and movie producers) continue making money the old fashioned way rather than adapting to the new media. The new media tends to favor the artist over the producer, which producers don't like very much since there's a lot of money to be earned in production.

Finally, I went to Running Your Language on Parrot with Chromatic and Patrick Michaud. One of the things I regret leaving K-State for is the fact that I no longer get to play with Parrot as much. I was hoping to use Parrot more to teach my class on Computer Architecture, but, alas, I don't have much need to play with it as a web developer. However, the talk showed me all the new cool toys they've added in the last two years since I've played with it and it's getting to be very nice indeed. If you have a chance to play with Parrot, I highly recommend it.

The End of the conference. I didn't go to the last talk since I wasn't very interested in Open Source Hardware (I'm really not much of a hardware guy) and worked on some stuff for Jifty instead.

Friday: Corvallis

Lance standing next to the Gentoo Servers at OSL

After the conference ended. Seth and I grabbed some lunch at the Doubletree, picked up a rental and headed south to Corvallis. Corvallis is the home of Oregon State University, where Lance now works for Open Source Lab. He gave us a tour starting with meeting his boss who was still around waiting to start an after hours meeting. He then showed us the lab itself including many of the Open Source projects they host. He took us in to his office where one of his students was still working to fix some DB problems with Drupal.

The OSL server status board

I'm a little jealous of Lance and all his toys. However, I enjoy software development far more than I enjoy systems administration, so I'm not that jealous (but a little). OSL has a very nice facility, much nicer than anything I had at K-State. Lance also has some phenomenal students working for him. I am jealous for that being the lone wolf at my current job.

After the tour, we went out to Newport and had some seafood on the bay and then headed back to Portland. Seth and I said farewell and so ended my time in Portland.

Saturday: More Travel

My trip back to Manhattan was pretty uneventful, so I won't bore you with anymore details.

I had a lot of fun on my trip to OSCON and I look forward to making the trek again next year.

Cheers.

Update: (2007-09-30) Corrected references to Andy Lester. Thanks for the correction, Andy.

For a three years now, one of my favorite IT tools on my bat-belt has been RT
from Best Practical
. RT (Request Tracker) is just another bug/incident tracker, but it's got a lot of great features like seamless email integration, highly customized access control, a self-service web site, and the ability to make public replies and private comments on any ticket in the system (allowing you to keep the shop talk as technical as you need to record solutions while only giving the end-user an overview of the solution).

I noticed in the last couple months that Best Practical has created a new service web site called Hiveminder
, which is basically just a to do list manager. However, as to do list managers go, it's pretty nice. I've been using it for a week now just to see how I like it. The jury is still out on that one.

Of course, I'm never satisfied with just seeing a service, I wanted to know how it worked. I initially thought that Best Practical might have adapted their RT to handle to do lists (which wouldn't be very hard) and added some nice JavaScript front-end enhancements. That is not, however, what they did. They've been building a web development framework called Jifty
on which Hiveminder is built. This isn't really news, but it was news to me so I added it to my list of things to look into when I had the time.

This weekend I decided to finally install it and give it a shot. So far it's wowed my socks off. Before this web site became just another part of my blog, I was working on a web framework. So far, Jifty is the web framework I would have written if I'd really had the time and experience to make it happen. I'm building a very small image gallery application to see if I can get something more to my liking than anything I can fid that's already written. I'd say that after a few hours (thoroughly interrupted by feedings and calming a 1 week old) I'm well on my way to something very nice.

If you're familiar with DBIx::SearchBuilder
(used extensively by RT and, I believe, written for it) or with the internals of RT, Jifty will look familiar as well. They've reused a lot of similar ideas. For example, Jifty::DBI
is the database development framework, which is pretty much a rewrite of DBIx::SearchBuilder with a lot of the functionality that RT extended it with and an extensible new way of writing database schemas. Jifty itself does almost everything for you automatically and then you can choose which parts of the built in functionality to override. It provides some nice tools for making your site look really nice and have that all-in-one-page-Ajax-feel.

Anyway, I'm pretty excited to see what I can do with it. If I successfully put together the image gallery application, you can look forward to seeing it here sometime during the next month.

Cheers.

I'm kind of excited to have an article
listed on the front page of Perl.com
, one of the sites run by O'Reilly & Associated
publishers. I hope it will be the first of several and my employer has offered to let me spend time during work developing articles such as this.

Anyway, if you have any interest in using Java, Perl, or just the Content Repository API for Java from Perl, read my article on Perl.com: Using Java Classes in Perl
.

Cheers.

As a fan of Perl, I'm very used to lists of items that are written with an extra comma. For example:

my %hash = (
     foo => 1,
     bar => 2,
     baz => 3,
);

Even though there's not a fourth item in the list above, it still works. This is commonly referred to as the "trailing comma." Switching languages, the trailing comma is supported by Mozilla's JavaScript 1.5 implementation
. It is not, however, supported by IE (not even IE 7).

Therefore, when I perform a very similar operation as above, I have a nasty habit of forgetting this and breaking my code in IE:

var hash = {
    foo: 1,
    bar: 2,
    baz: 3,
};

The above runs fine in Firefox, but will fail to run with an error in IE 7. When supporting IE, you (I) must remember to remove the trailing comma:

var hash = {
    foo: 1,
    bar: 2,
    baz: 3
};

Okay, so some newb is probably reading this wondering, why is the trailing comma valid at all? Simple. It makes it just a little easier to add another element to the list later and even to reorder with copy and paste line-by-line. It can save just a small bit of time coding. That is, I could paste "qux: 4," into the first JavaScript example above foo, below foo, below bar, or below baz without worrying about it if I am able to use a trailing comma. In the second example, I can insert it above foo, below foo, below bar, but not below baz. Furthermore, after adding the comma after "baz: 3," I still cannot put it after baz until I remove the comma from the end of the pasted "qux: 4." This might save me only 20 seconds in my coding of paste, click, comma, click, backspace, but a little thing like this goes a long way in helping my sanity.

Anyway, I just thought I'd post this real quick in the hopes that I'll remember next time.

Cheers.

Launches and Launches

Ooblech. I'm tired. I better get this posted and then get some sleep.

I'm excited to announce the two new site launches: this web site and a new Boomer.com. The latter has involved 6 months of my blood, sweat, and late hours. The former took me all of today to revamp and re-re-re-re-re-release. I'm also working on launching about three other web sites in the near future.

Home Site

As I stated previously, I'm going to start toning down the development I do at home. Well, at least that was the plan. It didn't really work as I thought. I've probably spent almost as much time in front of a screen at home as at work over the last few months. The reason is related to some work I've been doing with Perl and Java---which, incidentally, might be published on Perl.com in the next few months.

I've been toying with the idea of using a Java-based database engine called Jackrabbit with a Perl web front-end called Catalyst. While that was a fun project to work on, the results weren't quite as nice as I wanted. Rather than continue tweaking it into what I want (which would probably only take another month or two of effort), I'm going to take what I've learned and move on to using Drupal again instead.

Why back to Drupal? Well, I was using WordPress, which is a pretty decent blog app. However, it's just not as easy to hack as Drupal is and I know that if I have a blog, I'll still want to tweak it, but that's not so easy with WordPress. Furthermore, I'm webmaster for the extranet site at work, which is Drupal, and our church web site, which is Drupal. I figure I can maximize my ability to maintain all these Drupals. Drupal is an excellent general purpose CMS even if it's a little bit of overkill for a blog.

I'm also starting to contribute to a number of different web sites and I'd like to have one central location to collate all those contributions and I hope to make this the place. With some enhancements, I think either the built-in or one of the other aggregation modules available for Drupal will come in handy for this. I also have a kiddo on the way and plan to share photos here. That is to say, this isn't going to be just a blog for long.

Finally, as I mentioned I did learn something from the Perl/Jackrabbit integration and I plan to use some of that to improve the user interface of Magnolia (see below) and/or Drupal. I'll probably write a blog on what I learned in the next few days so that these thoughts aren't quite so nebulous.

Boomer.com

Boomer.com is another interesting beast. I'm still trying to decide how I feel about what we've done. It looks pretty good. Though, the look will never look as good as either Eric or I want it to. Being so close to the project, I know all of its blemishes. Like home remodeling projects, when you fix something, there are inevitibly a few mistakes that bug you, but when you look at project by someone else, you never even notice them. It's the same way here: I will always know what isn't quite as nice as it could be even though almost no one else will notice.

As for the technology, we've actually built a hybrid of Magnolia and Drupal. That's mostly interesting because Magnolia is written in Java and requires a Java-based application server, while Drupal is PHP based and requires CGI or an Apache module to run. There are some tools to help PHP and Java communicate server-to-server, but we haven't used any of them, mostly because we couldn't get them to work correctly within our timeline.

However, I'm pretty happy with how well the integration works. The most interesting project related to this so far has been the implementation of single sign-on, which required some interesting redirect tricks. It works pretty well and I'm confident that our customers will be completely oblivious to the nuts and bolts of the process. I'll probably blog on the single sign-on process in another blog coming up, so look for it! ;)

Just because we launched, though, doesn't mean we're finished. There's a long list of new features to add. Since I'm not sure how much of that list is safe to tell, I'm going to just say that we hope to sell more stuff and hope to add more multimedia and hope to put up some additional web-based applications to facilitate our consulting; that ought to vague enough. :P

Other Sites

I'm also working on a few other projects. A couple of them I don't really want to talk about except to say that I'm working on them. ;) However, our church web site is one of the biggies I'm currently working on. This is another Drupal site. First, the web site is currently running an old version of Drupal (either 4.5 or 4.6, I don't remember which and 4.7 is current). Second, the church has been redesigning the look of our logo, letterhead, signage, and web site. The web design has been chosen and Eric and I will be putting that together as soon as we can.

Anyway, I'm excited about that and the fact that the church will be starting a monthly newsletter to help drive new traffic to the site. I hope this will improve communication for our members, which has been a historical problem of our church (as it is with so many).

That's what I'm working on. As I said, I'm tired and now it's time to sign off.

Cheers.

Launches and Launches

Ooblech. I'm tired. I better get this posted and then get some sleep.

I'm excited to announce the two new site launches: this web site and a new Boomer.com. The latter has involved 6 months of my blood, sweat, and late hours. The former took me all of today to revamp and re-re-re-re-re-release. I'm also working on launching about three other web sites in the near future.

Home Site

As I stated previously, I'm going to start toning down the development I do at home. Well, at least that was the plan. It didn't really work as I thought. I've probably spent almost as much time in front of a screen at home as at work over the last few months. The reason is related to some work I've been doing with Perl and Java---which, incidentally, might be published on Perl.com in the next few months.

I've been toying with the idea of using a Java-based database engine called Jackrabbit with a Perl web front-end called Catalyst. While that was a fun project to work on, the results weren't quite as nice as I wanted. Rather than continue tweaking it into what I want (which would probably only take another month or two of effort), I'm going to take what I've learned and move on to using Drupal again instead.

Why back to Drupal? Well, I was using WordPress, which is a pretty decent blog app. However, it's just not as easy to hack as Drupal is and I know that if I have a blog, I'll still want to tweak it, but that's not so easy with WordPress. Furthermore, I'm webmaster for the extranet site at work, which is Drupal, and our church web site, which is Drupal. I figure I can maximize my ability to maintain all these Drupals. Drupal is an excellent general purpose CMS even if it's a little bit of overkill for a blog.

I'm also starting to contribute to a number of different web sites and I'd like to have one central location to collate all those contributions and I hope to make this the place. With some enhancements, I think either the built-in or one of the other aggregation modules available for Drupal will come in handy for this. I also have a kiddo on the way and plan to share photos here. That is to say, this isn't going to be just a blog for long.

Finally, as I mentioned I did learn something from the Perl/Jackrabbit integration and I plan to use some of that to improve the user interface of Magnolia (see below) and/or Drupal. I'll probably write a blog on what I learned in the next few days so that these thoughts aren't quite so nebulous.

Boomer.com

Boomer.com is another interesting beast. I'm still trying to decide how I feel about what we've done. It looks pretty good. Though, the look will never look as good as either Eric or I want it to. Being so close to the project, I know all of its blemishes. Like home remodeling projects, when you fix something, there are inevitibly a few mistakes that bug you, but when you look at project by someone else, you never even notice them. It's the same way here: I will always know what isn't quite as nice as it could be even though almost no one else will notice.

As for the technology, we've actually built a hybrid of Magnolia and Drupal. That's mostly interesting because Magnolia is written in Java and requires a Java-based application server, while Drupal is PHP based and requires CGI or an Apache module to run. There are some tools to help PHP and Java communicate server-to-server, but we haven't used any of them, mostly because we couldn't get them to work correctly within our timeline.

However, I'm pretty happy with how well the integration works. The most interesting project related to this so far has been the implementation of single sign-on, which required some interesting redirect tricks. It works pretty well and I'm confident that our customers will be completely oblivious to the nuts and bolts of the process. I'll probably blog on the single sign-on process in another blog coming up, so look for it! ;)

Just because we launched, though, doesn't mean we're finished. There's a long list of new features to add. Since I'm not sure how much of that list is safe to tell, I'm going to just say that we hope to sell more stuff and hope to add more multimedia and hope to put up some additional web-based applications to facilitate our consulting; that ought to vague enough. :P

Other Sites

I'm also working on a few other projects. A couple of them I don't really want to talk about except to say that I'm working on them. ;) However, our church web site is one of the biggies I'm currently working on. This is another Drupal site. First, the web site is currently running an old version of Drupal (either 4.5 or 4.6, I don't remember which and 4.7 is current). Second, the church has been redesigning the look of our logo, letterhead, signage, and web site. The web design has been chosen and Eric and I will be putting that together as soon as we can.

Anyway, I'm excited about that and the fact that the church will be starting a monthly newsletter to help drive new traffic to the site. I hope this will improve communication for our members, which has been a historical problem of our church (as it is with so many).

That's what I'm working on. As I said, I'm tired and now it's time to sign off.

Cheers.

Okay, so I'm really close to making a real release of Contentment following it's latest gutting and rebuilding. This time it looks nice. I owe a lot of the latest bit of nice-ness to Richard Hundt and his nifty Oryx persistence library. I discovered his bit of ingenuity via the CPAN RSS feed.

Anyway, I needed something that Oryx doesn't have (or doesn't have yet): cloning. For my readers which aren't programmers (and haven't already dropped out), cloning is just the word programmers use when we want two copies of the same data. Okay, so after a very small amount of effort I have added cloning.

The reason I need cloning is because I am adding the ability to seamless create object revisions. That is, it's nice when you are building a publishing system to be able to keep old revisions of data around. That way, if someone makes a change to a page that obliterates some important information, you can go back and fetch that information from an old revision of the document. I want this to happen automatically because I don't want folks who are building on to Contentment to have to think to hard about how it works. I just want it to work. I've discovered too often that if something isn't easy to do, it won't be done.

Thus, I want my code to look something like this:

my $obj = Foo->create({ title => 'Foo Version 1.0' });
$obj->title('Foo Version 2.0');
$obj->update;

After that code snippet finishes, there should be two foo objects stored in the database. One will have the title "Foo Version 1.0" and the other with the title "Foo Version 2.0". At the same time, I need to make sure that continued use of "$obj" uses the newer object. Which means that suddenly I have to make sure the entire internal state of that object now refers to the new one. Since the objects use Oryx, this would mean a lot of dinking around with internal state that could change with every new release of Oryx—i.e., a very bad idea.

I could create a special new method for created new revisions, but I don't really want a different syntax when that one I just showed is already crystal clear. The old revision isn't obviously in the database because searching for it will still only return the latest revision unless you specifically want older revisions. I'm not changing the interface so much as the implementation. Why should I muck up the interface?

Enter the power of Perl aliasing. In Perl, alias variables are special variables that don't really have any storage for themselves and exist only as second (or third or fourth...) names for existing variables. Aliases are a lot like references in C++. Also in Perl, variables are passed to subroutines in a special array named "@_". Each element of this array is an alias to the passed information.

For example, if I run the following snippet of Perl:

my $foo = 1;
my $bar = 2;
foo($foo, $bar, 3);

The special "@_" variable in the foo() subroutine will be set so that $_

package Foo;
# Return a simple empty Foo object
sub new { bless { }, 'Foo'; }
# REPLACE myself with a new Foo!
sub replace_me { $_[0
 = bless { replaced => 1 }, 'Foo'; }
package main;
my $foo = new Foo;
print "$foo\n"; # empty Foo object
$foo->replace_me;
print "$foo\n"; # a different Foo object!!!

This is wicked and probably not a good idea in most cases, but it demonstrates how my revisioning code will work. The output of my code should look something like:

Foo=Hash(0x1801434)
Foo=Hash(0x18014a0)

Notice that the addresses listed after the type are different! By replacing $_[0] is the replace_me() method, I've overwritten $foo with a different value.

Therefore, all my code needs to do to make everything work after the call to the update() method, is to replace $_[0] with the newly created record object. I don't have to muck with any internal state and the API remains unchanged.

However, this does result in some potentially major-bad pitfalls that I need to be careful about—in fact, they might be bad enough that I'll have to find a different way to do this. However, I thought the concept was very interesting.

Pitfall #1: I better let the user know in the documentation that this happens or they might have problems that I can't anticipate.

Pitfall #2: If I switch the references without updating the original and some data structure uses a reference to the old object, the old object won't be properly updated. I don't think this is a major concern because there's only one place these objects should be directly referenced and I can control and update that one in the process of the update() method. Any other code that needs to create a reference to the object shouldn't be referring to these objects directly, if they are to properly obey the documentation given.

Pitfall #3: There are surely other side-effects that I haven't thought of yet.

I think the Perl aliasing functionality is one of those nifty but dangerous features. We'll see if I actually end up using it the way I've presented here...

I am never satisfied. I've been working on this thing for more than six years now. I finally rewrote it and rewrote it and rewrote it until I actually had something useful for the CIS Support Site. I think I've counted about ten major rewrites (or sometimes full do-overs) up to this point, so this makes the latest rewrite I embarked on two weeks ago number eleven.

In April, I suggested that I was Outgrowing Mason. Assuming that I complete the 0.11 branch of Contentment, Contentment is no longer Mason-based. Mason is really a nifty thing that I will use again, but Contentment was really abusing it. Mason is kind of a mini-CMS with a custom templating language, rudimentary file handling, and some other extras. The templates use Perl embedded in text which is neat-o for rapid templating of stuff—which is what I wanted with Contentment in the first few revisions (especially back before I knew that what I was doing would become Contentment 0.7—a do-over since 0.5 was a completely different code base). Mason mirrored some of the features I needed.

What I wanted at the time, was a way to easily identify the type of a file and dynamically convert that into HTML and then render that HTML in a custom theme. I also wanted the ability to auto-generate indexes of the files. The system used no database and, though I experimented with it a couple times, no caching. However, as I moved through Contentment 0.9 to add database support, form-handling, improved theming, etc. things started to get messy. The layered file system Mason wants to use is really not very flexible. Technically, you're supposed to be able to replace the file system resolver module with a custom handler, but that doesn't work very well. I did it, but had to hack in a couple of ugly spots to get it to work.

Also, embedding programming languages into text is my idea of a bad idea for anything but the simple. In my opinion, logic and content should not mix whenever possible. Thus, most of my Mason components were either 95% Perl or %95 HTML with a smattering of Perl. I don't need Mason in this case, I can just use Perl scripts directly or a templating language that doesn't mess up my HTML with embedded Perl.

Finally, Mason really hates handling non-Mason content. I'd managed to do it through creative use of autohandlers and dhandlers, but the solution was slow and unsatisfying. Contentment doesn't care what kind of file it's serving, so Contentment and Mason were again mismatched.

Without Mason, I was suddenly freed of several restrictions. Before I had organized the entire layout of the web documents under a directory named "docroots" which contained a "master" document root and a "site" document root, which were layered on top of each other in the usual Mason way. This was ugly. It made it hard for anyone unfamiliar with the system to find the files they were looking for and it resulted in all the features of Contentment being mixed together with a minimum of encapsulation. (I'm a computer scientist, I must have encapsulation!)

Additionally, each installation of Contentment required it's install directory to work well (including a generated Contentment::Config module to tell the system where to find it). This meant that the typical CPAN installation could not work well. I want this module to install with the usual CPAN way because it makes adoption of Contentment that much easier:

cpan Contentment

WIth the 0.11 rewrite, I now have a single document root, named "htdocs" (a familiar title). I have moved all of the Contentment specific stuff into a folder named "plugins" that separates the functionality into logical groups that can be loaded or not. This layout also eliminates the need for a custom library install and configuration module. Now, you just need to know where your plugin directory is kept.

The CPAN install thing is still a little iffy because while just running the above command should work (once I make a release), you won't have a working install without a plugins directory, the htdocs put into the correct place, and some other configuration. I'm working on a post-install setup script that will help with the rest. Since we have to configure a web server to use the app, I can't see how we can get it any simpler than this. At this point, the install looks more like:

cpan Contentment
cd ~/.cpan/build/Contentment-*/
bin/setup-contentment

That won't work everywhere, so I'll probably come up with directions assuming a direct download and let the CPAN'ers figure out the rest from that. You'll have to read the docs to get anything useful anyway, so it's probably not a big deal.

Anyway, I really, really like where this is going currently. I'm hoping to have the old system dropped into 0.11 in another couple weeks and to have my web site operating off of it shortly thereafter. We'll see. I also need to update all the documentation. It's mostly right still, but the changes will require some tweaking.

Cheers.

I finally got a new release of Contentment out yesterday. I've been working on this for almost two months as I'd created bunches of nasty bugs with a few big changes I'd made recently. I've got to start using the inards of Subversion a little better (temporary branching would have made this a much smaller problem).

Anyway, with this new release the Contentment web site is again running the latest version of the software and has the latest documentation available online. Now that Contentment is working again and that I've gotten the VFS system to a very nice point, I'm going to start porting this blog and such to it. Once done, Contentment should be very nice and I'll probably start promoting it a bit more.

The latest version uses File::System as the basis for the VFS, which is much more advanced that the previous VFS system. I hope to expand the use of this system in the next release to allow for arbitrary SPOPS objects to be used as backends for the VFS.

This version also features a hooks system, which is used to implement session and context creation and also the transformation and filtering system (or rather the request has hooks that these systems are added on to). This means that themes, transformations, filters, etc. can be replaced or removed if someone doesn't like them. I think I will place the caching system here as well. Furthermore, I think the filter and transformation systems will utilize the hooks rather than the rather stupid module loading system used now. The file typing system (both for input types and for output types) will also be reimplemented using the hooks system.

Those are the two biggest changes as of this release besides the bug fixes allowing the system to actually work now. I will try to make releases more frequently in the future and will try to break the system less often. (And I need to port the old aggregator so that the Contentment web site can pull these blog entries...)

Outgrowing Mason

It's a good thing Terri's coming home tomorrow. I don't think my body can take many more of these late nights. (I.e., my wife is out of town for a conference, so I pulled late nights this week, since I don't when she's home. :)

Background: The latest idea for Contentment, which is the real working idea originally came by basically adding some customizations built with HTML::Mason. Mason is a nifty mini-CMS/embedded-Perl templating system. It's hard to classify because it has a really wide mix of features. It serves files, it provides a layered virtual file system, it provides a templating engine, it provides some fancy features for wrapping content with other content via "autohandlers" and filtering, etc. To paraphrase Strong Bad, "It beats the pants off that ol' washed up the PHP I used to use."

So, I extended it. Initially, I added an indexer and a template system. Well, I had to use some odd tricks to get that to work, but I think Mason still did it pretty well. I added a system for handling contextual and session information. I brought SPOPS into the picture to help out with the database end of things (and then I hacked that because the so-called last S=Security is S=Stupid Security, at least for my needs.) I've added a fancy transformation system, which I've revamped to make it even better. I've added a fancy filtering system to be applied after transformations (which should go through the same refactoring that transformations did). The latest addition is the VFS system. I've written a new project, File::System to handle the new needs I have for URL mapping and the soon to come URL to database record mapping I have in mind.

What does this all add up to? I'm seriously abusing Mason at this point. I've taken my good ol' friend Mason and ripped his guts out, strung them around the room, and replaced parts with my own PVC. Okay, that's disgusting. Man, I go weird at 4am...I should sleep.

Basically, I'm going to have to evaluate things more, but I think that I've already spotted the next set of updates. Mason is going to say, "Sayonara." Or at least, partially. It's still going to be a valuable part of the system, but it won't be the front end anymore, I think.

Anyway, I'm never satisfied. I don't know who said it, but in the "Camel Book" by Larry Wall, Tom Christiansen, and (originally) Randall Schwatz (though, he's since been gypped, I understand), the three virtues of programming are Laziness, Impatience, and Hubris. I think a fourth one to add to the list is Discontent.

Yes, very punny. Good night.

Form processing

Once I start on a problem I have a difficult time letting go until I have a solution. I mentioned forms processing in my last entry and I have been crunching on it ever since.

I have found that the major problem with the original design had more to do with a poor OO methodology than a bad design. I just need to get the pieces separated into the correct objects. Therefore, I've build a new OO API for forms processing.

Okay, I've separated the system out into the following pieces:

  • Context - a transient object that collects all the information pertinent to the current request
  • Session - a persistent object that collects all the information connected with a particular user's session
  • Setting - a persistent object containing application-wide settings
  • User - a persistent object containing information about a user that exists across sessions
  • Form - an object stored in Settings that describes the structure of a form
  • Submission - a transient object that exists initially when a Form is written to a response and again if the user POSTs that form back in a request
  • Action - a functor object that performs some action using data from a processed Form Submission
  • Widget - an object that both renders some set of controls in a response used to form a POSTed request and a functor that performs some processing of Submission data on behalf of a Form before the form's Action is executed
  • Map - an object used to determine how the response should be constructed when interacting with a Form
  • Panel - a box in the response containing whatever object the Map says it should contain, the topmost Panel, __DEFAULT__, can be used to affect the entire response

The use-case is basically like this: The response has a Panel placed in it (possibly the __DEFAULT__). This Panel specifies a Map, which determines what sub-response to place within the Panel. Typically, this is some sort of Form, to being with. The Form is drawn to the response and stored in the Settings (keyed by a application-unique name). The Form determines the Action that is run on the receipt of an activated Submission. A Submission is initially created to associate a UUID with the submission and to remember the Map used so that an activated Submission received later will operate according to the original Map behavior. Finally, the user gets a copy of this form in her browser and fills in the details of the form. Once filled, the form is submitted back, which creates an activated Submission object. The Submission object then causes the Form to process all the incoming information via it's Widgets. Assuming successful processing by all Widgets, the Form then runs the Action. Based upon the Action result, the Map is then used to determine how to render the response. This generally involves an immediate 302 Redirect to the next page in the Map and then the Map is used within that page to determine how to render the content there.

Phew! The details of this whole process are almost entirely handled internally to Contentment (or will be when I release the next trunk revision). The only the thing the programmer will have to do is to create a Form with Widgets, create an Action to handle the Submission, and a Map to determine what to do next, based upon the output of the Action. This creates a nice HTTP-centric MVC architecture where the Action/Map form the controller, the Submission forms the model, and the Form/Widgets form the view.

Contentment is currently running two sites: Contentment.org and ~Sterling. I'm currently updating the CIS Support Site to also run under the new software. The process of conversion is pretty simple since a lot of what Contentment is came from the "knowledge base" used there.

I've discovered a few minor flaws in Contentment at this point that will need to be addressed soon. Primarily, to this point, the forms system that I've built is rather badly unfocused. I made some assumptions (which I stupidly did not document), which no longer hold. As such, I need to refocus the design of this subsystem as it is a major feature. This has come into play because two of the most important pages on the CIS Support Site are the password change and account application forms.

The forms system is actually very good at handling complex forms situations, but as for simple stand-alone forms, it sucks. Anyway, I just wanted to cover the basics of web forms and why they are a complex situation to be resolved.

Current HTML forms are dumb. Eventually XForms will replace them, but until then this system operates within the restrictions of HTML forms. HTML forms have a very small set of possible controls: text boxes, password boxes, checkboxes, radio buttons, buttons, popup boxes, list boxes, file uploads, and text area boxes. The HTML form also assumes that a given form only addresses a single action at a time, which is a very difficult limitation to live with if you want to do something even moderately complicated (like updating more than one record at a time).

This limitation can make having multiple nested forms very difficult or impossible (especially since a form tag cannot be embedded within another form tag). Even having multiple separate forms on a page can lead to complications. As such, I created the idea of "panes" where each form exists within a pane. Then, a pane may contain other panes and thus nested forms. Upon submit, the forms processor is run and processes all submitted panes that have had their "activate" field set. This actually works alright, but what if we don't want to use a pane? Well, that isn't handled so well.

Another problem with forms is what to do with the form when we're done with it. For example, what if we want to have a login form. We might want to have logins available on a stand-alone page or as a part of the side-bar. If a stand alone, where do we go after login? If a side-bar, do we return to the current page on success? Do we go to a special error page on error, or do we just report the error in the sidebar on the current page? Thus, I added a "map" system that allows pluggable module to determine how each action state is handled. This is a bit of overkill for very simple forms.

Beyond this, the system is a little esoteric. It requires a lot of extraneous API knowledge that could be simplified. There are also a lot of features that are a little out of place because of the time span that was involved from the start of the forms system and today (I started the forms system early last year). Anyway, this thing needs a bit of work and will probably be pretty well rewritten for the 0.9 release.

My next plans for the current revision are to reconstruct my blog aggregator and create a blogging plugin. I was thinking of rewriting the VFS to add it's first non-real-file-system plugin, but I think I'll create the plugins using the file system first and then try the VFS update afterward. I think it will make the VFS plugins a little more interesting if I start without them and then add them in later.

I need to also start posting documentation on the Contentment.org web site this week so all of this makes sense without having to read the code. So much work to do and so little time...

Neat. ~Sterling has been rebuilt using the latest CMS to take the Open Source world by storm...er something. Okay, so the "secret" project I've been working on for years is finally doing something because I decided to stop being "elegante" and decided to JustMakeItWork(tm).

What have I done? Well, I wrote a little tool to help me manage the CIS Support Site for work. This little tool is a combination themer/indexer for static pages. It also does some on-the-fly generation of HTML from reStructuredText, which is what we write most of our docs in. It seemed pretty useful and is similar to the software I was using to run this site before October 2004, called Blosxom, which is a lightweight file-based blogger.

Anyway, when I had some trouble getting access to K-State Online for my course last semester, I decided to try and dump my course data into it on ~Sterling. With a few modifications it worked quite well and quickly supplanted any previous ideas I had about the content management systems I'd been toying with for the past several years.

Most of the work is already done by HTML::Mason. My system just took advantage of the features already present to add indexing and theming and generation of content from other formats. ~Sterling took it a bit further by adding the ability to generate even more complicated content (especially, ripping apart zipped Keynote "files" and using XSLT to generate HTML outlines).

At this point, I ran into a few issues:

  1. Adding new generators was requiring lots of custom code and my indexing code was becoming convoluted.
  2. New content had to be added with care, otherwise Mason would try to interpret files it had no business touching. When this happened, my indexer would basically bring the entire site to it's knees with a single exception.
  3. Some content is just better stored in a database. Blog entries, news items, and simple records are just a few examples. The system had no way of coping with any of these.

Thus, since about the time I put Drupal on this site, I've been working on a replacement. Drupal is merely a temporary expedient. I started completely from scratch, but have dragged in a lot of the bits from the existing "knowledge base" system to build this new system, which I am dubbing as Contentment (superceding all the predecessors I'd created and called this).

This system currently features a lot of unused features, but most of the good ones are employed currently. One of the best features I just added this week and after just a few days it's practically remade the quality of the system. Specifically:

  1. It features a (largely unused, as yet) forms handler that can help design forms and wizards with a fairly small amount of effort. I borrowed a lot from the kinds of work that Everything has done in this area.
  2. It uses the SPOPS object-mapping system to provide a database API. It's not required that new plugins use this API, but all the existing database pieces use it.
  3. The system automatically provides for context, sessions, and logins. The user accounting system is completely pluggable, so new support for LDAP or other login types could be added with a little effort.
  4. The system provides a basic permissions system. All of these features have been designed to make adding database-based plugins possible, but there really aren't any yet.
  5. The major feature that has really made the system work despite the lack of any database plugins is the VFS system I've put together. I've debated whether or not this should be forked into a separate project, but I'm going to leave it where it is for now. Anyway, this enhances Mason's abilities by quite a bit and allows for a much more general way of looking at files. This way, Mason no longer has primary control of generating files, but passes that control off to other plugins.
  6. Right now the system works via CGI, but I'd like to put together a mod_perl front-end to take advantage of those features. I've designed everything to this point with mod_perl in mind, so it should work with minimal effort.

That's a pretty bad mish-mash summary of the features. There's a lot more I could say, but I'll save that for documentation. I'm going to admit that I've had a SourceForge project for this for eons, but that it'd never really worked until now. I'm so excited about how this is going now, that I have registered Contentment.org and will be posting information and documentation there. I'm going to, for now, use the mailing lists, bug trackers, announcements, and CVS repository at SourceForge. (Though, I'm hunting hard for a way to keep it in Subversion as I strongly prefer it, despite it's performance and other issues.)

Anyway, I wanted to announce that and say that Drupal may be saying farewell to this site soon---if I can get the plugins written and translate all of my Blosxom and Drupal entries into my new plugins.

Just Another Perl Hacker

There is exactly one aspect of Perl that annoys me and it's the same aspect that everyone makes fun of Perl for and it's exactly the reason I love Perl too: JAPHs. JAPH = Just Another Perl Hacker. The Perl world is filled with JAPHs.

I think Computer Science is divided into several overlapping camps. You have the mathematicians who think that CS who spend their time with theory and showing that programs and designs are provably correct. You have the software engineers who want to model everything and then do almost no coding and then use the model to verify the code. And then, you have the hackers who just like to play and want to figure things out on their own on their own terms.

I've come to believe I stand in the last group. I like to beat an idea to death and I'm never satisified with any result short of perfection. I don't have the patience for mathematics (nor the brain). I just don't think that way. And software engineering strikes me as more like a cross between bad wizardry, meteorology, middle management, and a pipe dream. Who wants to draw models according to someone else's idea of a good diagram? *co-UML-ugh* I've taken my SE and math classes and learned from both, but I can't really say I like either camp. Finally, I design in vi, I code in vi, I research with Google, and I use print-statements and logs to debug my code. I'm definitely in the "hacker camp."

The term "hacker" has received a lot of press and has been generally defined by the culture, but I think the term finds it's most appropriate meaning in it's original denotation: a dude that literally hacks away at something until he gets what he's looking for or just broken pieces. The term hacker has come to mean: a dude that likes to break into systems and read your email. However, that's more of the realm of the Script Kiddie. Anyway, I digress...

Back to Perl: The problem is that Perl code is extremely expressive. That's why us hackers like it. I feel like saying, "do this or do that", then I say , "this or that." Or, if I prefer "unless this do that," then I say, "unless (this) { that }." Or, "that unless this" or "that if not this," etc. I can think in Perl. I can design in Perl. Perl doesn't enforce very many policies, so I get to choose my own. That's Perl's beauty.

This lack of policy enforcement is also it's bane. As one of the CIS professors (in a Japanese accent) stated during my MS Presentation (just got my diploma in the mail today, btw), "This language is very strange to me. Why did you pick this?" I like it. I didn't tell him that, I gave him the BS about it being the language of the tools we already use. (BS only because I chose those tools partly because of their language, though RT is head and shoulders above any other similar tool I've taken a look at.)

The problem Perl has is that so much of the code written in Perl is simply hacked together. This means that CPAN (a great feature of Perl), has to be carefully sifted to find the module that fits your need. For example, if you need a tool for object persistence, there's Tangram, SPOPS, Class::DBI, Alzabo, DBIx::SearchBuilder, and a few others. Each has their own strengths, but all of them were written by hacker types with more or less lenience towards the math and SE mentalities. I'd say Tangram is the most mathematical and Alzabo is the most SE. DBIx::SearchBuilder is completely in the hacker camp. However, I think they all find themselves written from the JAPH perspective: hacking is a fact of life in Perl.

I'm looking forward to Perl 6. I think part of the reason so much Perl is so hackish is because the Perl 5 language is so hacked. Larry Wall built a simple tool for processing log files and then hacked on more and more features until he got to Perl 5. Now, we have hacked on object support. Hacked on packages. Hacked together subroutines. Hacked together regular expressions. All of it is brilliant, but the "cruft," as Larry Wall calls the entropy that hacking inevitably brings along, it has started to take over. Perl 6 should freshen the slate, especially since the development is very heavily design driven. Anyway, in another year or two when the preliminary versions of Perl 6 start coming out, we'll see.

Enough ranting....now for more hacking....

2  

Tags

Find recent content on the main index or look in the archives to find all content.