Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Thursday April 20, 2006
09:12 PM

Class::CGI 0.12 to the CPAN

[ #29394 ]

I've just uploaded Class::CGI 0.12 to the CPAN. It's the same module I uploaded earlier today, but with some minor documentation errors fixed. I've also changed all handler names in the documentation away from Class::CGI::HandlerName to My::...::Handler because I don't want to encourage folks using the Class::CGI:: namespace.

The reason for this is straightforward: I want to encourage others to write general purpose handlers and upload them. I plan to write and release Class::CGI::DateTime. With this handler, you'll be able to specify drop-down fields like "day", "month" and "year" and get a DateTime object for them merely by doing this:

use Class::CGI
  handlers => {
    date       => 'Class::CGI::DateTime',
    order_date => 'Class::CGI::DateTime',
  };

my $cgi        = Class::CGI->new;
my $date       = $cgi->param('date');
my $order_date = $cgi->param('order_date');

if ( my %errors = $cgi->errors ) {
    ... handle errors
}

The "order_date" would be handled by expecting parameters named "order_day", "order_month" and "order_year". How this is done internally is an example in the Class::CGI docs.

I've also realized that I need to go ahead and incorporate a suggestion which allows me to specify which parameters will be read by a particular handler. This will allow one to write something like this:

use Class::CGI
  handlers => {
    md5 => {
      handler => 'Class::CGI::MD5',
      params  => \@param_names,
      seed    => $seed,
    }
  };

my $cgi = Class::CGI->new;
my $md5 = $cgi->param('md5')
  or checksum_did_not_match_param_values($cgi);

I'll have to give some more thought on how to do that, though. That's beginning to get a bit clumsy, so I don't want to go that route just yet. Making a clean, easy-to-use interface is far more important to me. I could make this work:

use Class::CGI
  handlers => { md5 => \&md5_handler_setup };

That would be easier and give more flexibility, but it might be confusing. Also, the profile file syntax couldn't support that easily, so I might have to implement the profile class idea. This would be useful for larger sites where taking a bit more time with up-front infrastructure is worth the trouble.

Ideas for other general-purpose handlers welcome.

Update: OK, I figured out a good solution for the "md5" problem listed above:

use Class::CGI
  handlers => { md5 => 'Class::CGI::MD5' };

my $cgi = Class::CGI->new;
$cgi->args( md5 => \%args );

my $md5 = $cgi->param('md5');

With that syntax, the hashref set with the &args method will be an extra argument passed to a handler constructor:

package Class::CGI::MD5;

sub new {
  my ($class, $cgi, $param, $arg_hashref) = @_;
  ...
}

And that would be effectively invoked as:

return Class::CGI::MD5->new($cgi, 'md5', $cgi->args('md5'));

It adds a bit more complexity internally, but not much. It also makes things very flexible without making unwarranted assumptions about what the user wants.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • The "order_date" would be handled by expecting parameters named "order_day", "order_month" and "order_year". How this is done internally is an example in the Class::CGI docs.

    Danger Will Robinson!

    I did that too. It hurt.

    It was after the second rewrite that I finally ended up with that namespacing and dot-seperators thing.

    So...

    order_date => 'Class::CGI::DateTime', ... should not break out of "order_date".

    Rather, what works really well is that it expects order_date.day, order_date.month, order_date.year fie
    • First, what is CGI::Tree? I couldn't find that.

      Second, I've deliberately adopted an approach which fits parameter names I'm seeing in most forms. I do admit that what you're doing is cleaner, but it's not what folks in forms seem to be doing. However, your approach does seem to be very workable. I'll think about it.

      Out of curiosity, why haven't you released any of that to the CPAN, or did I just not see it in your slough of modules?

      • Sorry, I got "CGI::Tree" from memory, I'll find you the proper name later.

        The reason I never released my stuff to CPAN was because it was too integrated into my AppSpace project to be able to break it out properly.

        It used a MetaModel (think something a bit like a Moose model) to do both the Class::DBI-like stuff, and the Class::CGI-like stuff. And because it was using MetaModel data to control the widgets, it would have been very difficult to get it out.

        Plus I screwed up in that the entire project had a dyn
    • I might addt that here's one way to support your dot syntax:

      package My::Handler::DateTime;
      use DateTime;

      sub new {
          my ($class, $cgi, $param) = @_;
          my @params = qw(day month year);
          if ('date' ne $param) {
              @params = map { "$param.$_" } @params;
          }
          my ($day, $month, $year) = map { $cgi->raw_param($_) } @params;
          return DateTime->new(
              day   => $day,
         

    • order_date => 'Class::CGI::DateTime' should not break out of “order_date”.

      Did you actually look at Class::CGI? It has no conventions whatsoever regarding parameter naming. You can do your beloved dot-based namespaces just as well as someone else can choose not to. Given order_date, it is entirely up to Class::CGI::DateTime to decide whether it wants to consume qw( order_year order_month order_day ) or qw( order_date.year order_date.month order_date.day ).

      • You sound bitter.

        Certainly it is up to order_date what it wants to consume.

        Just as it's up to Class::CGI whether it wants to use Class::DBI as well, or up to Class::CGI::DateTime if it wants to spread it's code around into Class::CGI::TextBox and Class::CGI::DropBox.

        Except that although you can do this, you shouldn't.

        If you have n Class::CGI objects on a page, how do you share out the names? It naturally becomes a namespace, just as Perl uses namespace. That it is a dot is a matter of personal preference, i
        • I’m not arguing about the merit of namespaces or of employing them. I’m saying that these issues are orthogonal (and hence irrelevant) to Class::CGI’s interface, so there’s no need to keep harping on them. This is the third time you brought it up – it’s okay, we got it. That’s all; no bitterness.