Welcome to WebmasterWorld Guest from 54.166.46.226

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

Command Structures Revived

Didn't have an answer then - have one now

   
8:03 pm on Nov 22, 2009 (gmt 0)

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member



This is the revival of an unanswered question from a few months back. At the time I didn't have an answer of any real value but have come across an implementation of something very cool.

The question was (paraphrased) inquiring about a graceful method of dispatching commands. I'm **mostly** a linear coder, and most of my programming is the stock inline Perl we're familiar with (and often despised.) I do work with Perl OOP, but often found the overhead of multiple modules unnecessary for smaller projects.

The one I've found is a current project that uses CGI::Application::Plugin::AutoRunmode - the stock CGI module combined with the Application module and AutoRunMode plug in. It also uses the template toolkit for output, making it even more compact and portable.

Basically, there are no configurations, no &calls_to_subs, and the autorun module manages everything based on the input from query->param. It runs under strict and -w just fine. A typical "framework":


#!/usr/bin/perl
use strict;
use warnings;
# Note there are no calls to functions here -
# in this example, a custom path to site_perl is needed.
BEGIN {
my $homedir = ( getpwuid($>) )[7];
my @user_include;
foreach my $path (@INC) {
if ( -d $homedir . '/perl' . $path ) {
push @user_include, $homedir . '/perl' . $path;
}
}
unshift @INC, @user_include;
}
MyPackage::App->new->run unless caller;
package MyPackage::App;
use base 'CGI::Application';
use CGI::Application::Plugin::AutoRunmode;

That's it. The bolded line is what does the work, creating an instance of "MyPackage" as a module, even though it's not a real module or package you would access from use.

The functions are managed by incoming query strings, such as

rm=my_function

Where rm is "run mode." There are two required functions, setup in which you set up all program configurations, and StartRunmode:


sub setup {
my $self = shift;
## using generic "package name references" here
$self->config(
some_package_config (
SOME_OPTION =>
{ SOME_KEY => 'option_value' },
{ SOME_OTHER_KEY => 'option_value' }
),
some_other_package(
SOME_OPTION_TOO => { SOME_KEY => 'option_value' }
)
);
}


sub my_startup : StartRunmode {
my $self = shift;
my $record_id = $self->query->param('rec_id');
# etc.
}

my_startup is what displays on initial load of the program. Then you build functions as you need them in Runmode.


sub some_function : Runmode {
my $self = shift;
## code here
}

... which is accessed by rm=some_function in post or get. A question for those that have worked with this, does this present security issues? Would it be better the define an alias or mapping hash in sub setup?

For many of you this may be old news, but if you're familiar with Perl OOP at all it's an awesome tool. No inline scripting, no configurations at the top of the script, no calls to functions.

I have found, however, like most packages there are some areas that are a little more difficult to sort out when a quick 20 lines of linear code would be more straightforward.

[edited by: phranque at 11:16 pm (utc) on Nov. 22, 2009]
[edit reason] disabled graphic smileys ;) [/edit]