Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Ubiquity of the CGI param method

by jwark (Novice)
on Aug 10, 2010 at 14:34 UTC ( #854059=perlquestion: print w/ replies, xml ) Need Help??
jwark has asked for the wisdom of the Perl Monks concerning the following question:

I have been using the Data::FormValidator package and have found it to be quite helpful.

I have noticed that this package (and others) makes use of the CGI param() method to validate information *OR* it requires a object that has its own param() method that functions the same as the CGI param() method.

I was wondering if a package existed on CPAN that, when used, produces an object that simply has a param() method. My thoughts were that it would be leaner to use such a package for non-CGI type validation. You could simply load some parameters into it, and then use it with Data::FormValidator (or some other package requiring a param method).

Also, on the surface, the param method seems pretty straight forward to implement, but I am sure I will miss some edge cases which would just be annoying. Perhaps there is some sort of standards page that describes the way the CGI->param() method works, like an RFC.

In all honesty, I haven't used the Data::FormValidator without a CGI object yet, but the apparent usefulness of the param method indicates that there should be a simple package that gives you that method (in object form).

Any information leading to such a simple package/method would be greatly appreciated.

Comment on Ubiquity of the CGI param method
Re: Ubiquity of the CGI param method
by LTjake (Prior) on Aug 11, 2010 at 01:14 UTC

    I *think* I see where you're going with this. Basically you want arbitrary data structure validation.

    Typically people call the "profile" for such validation, a schema. You'll see that term most frequently with XML data.

    In the Perl world, there are no doubt a number of tools that let you validate data against a schema. One such tool is Data-Rx (homepage). One particularly nice feature is that the author has also prepared implementations in other languages, so the same schema can be used against a number of different end-points.

    Sorry for not directly answering your question, but I would feel silly if I didn't mention this existing tool.

    --
    "Go up to the next female stranger you see and tell her that her "body is a wonderland."
    My hypothesis is that she’ll be too busy laughing at you to even bother slapping you.
    " (src)

Re: Ubiquity of the CGI param method
by skx (Parson) on Aug 11, 2010 at 08:22 UTC

    I'm not sure there's any information on building such a thing - but actually doing so wouldn't be too hard.

    This is just a quickie I knocked up to test the idea. You could probably make it all objecty, and moosey if you preferred:

    package Object::Holder; use strict; use warnings; =head1 NAME Object::Holder - A module for working with parameters. =head1 SYNOPSIS =for example begin #!/usr/bin/perl -w use Object::Holder use strict; my $helper = Object::Holder->new( foo => "bar", bar => "baz" ); my @keys = $helper->param(); my $bar = $helper->param( "bar" ); =for example end =cut sub new { my ( $proto, %supplied ) = (@_); my $class = ref($proto) || $proto; my $self = {}; $self->{ "data" } = {}; # # Store the supplied key=>val pairs in our data section. # foreach my $key ( keys %supplied ) { $self->{ "data" }->{ lc $key } = $supplied{ $key }; } bless( $self, $class ); return $self; } sub param { my ( $self, $param ) = (@_); if ($param) { # return the value of the named param. return ( $self->{ "data" }->{ $param } ); } else { # return all the param names. return ( keys %{ $self->{ "data" } } ); } } 1; package main; my $o = Object::Holder->new( foo => "foo", steve => "kemp " ); # # Get all # my @params = $o->param(); foreach my $param (@params) { # # Get single # print "READ: $param -> " . $o->param($param) . "\n"; }
    Steve
    --

      Interesting. That appears to be pretty good for a quickie. That does look like it covers a lot of what I usually do with the param() method.

      However (and this goes back to wanting an RFC type thing), the param method does more. I believe that you are able to set values (not too bad to implement) and I believe that you are supposed to be able to have multiple values (array refs) per parameter. Again, I don't believe that those would be too difficult to implement off of what you presented here, but I wonder what other features I am missing.

      The Data::FormValidator (and I keep going back to that because it is the package that made me think about this) uses an object with a param method, but I don't know what features of the param method are used. Probably the most basic like you described above, but a complete param() method would be desirable.

      Thank you (both) very much for your time. If you have any more ideas, I would appreciate them.

        Allow me to throw my hat into the ring. I've tested this with Data::FormValidator and HTML::Template and it seems to work fine.

        package Object::WithParams; use warnings; use strict; use Carp qw/ croak /; =pod =head1 NAME Object::WithParams - An Object With Params =head1 VERSION Version 0.1 =cut our $VERSION = '0.1'; =head1 SYNOPSIS use Object::WithParams; my $thingy = Object::WithParams->new(); # set a param $thingy->param(veggie => 'tomato'); # get a param my $veggie = $thingy->param('veggie'); # $veggie eq 'tomato' # get all params my @params = $thingy->param(); # @params == ('veggie') # clone a Object::WithParams my $doodad = $thingy->clone; # $doodad->param('veggie') == 'tomato +' # delete a param $thingy->delete('veggie'); # delete all params $thingy->clear(); =head1 DESCRIPTION Use this module to create objects that do nothing except contain param +eters defined by you which you can get and set as you wish. Many modules su +ch as L<Data::FormValidator> have methods that accept an object with a param +() method and this object should be compatible with all of them. This module really ought to be a role but there is no standardized way + to do that in Perl 5. (Not everyone uses L<Moose>.) =head1 METHODS =head2 new Creates a new, empty L<Object::WithParams>. =cut sub new { my ($class) = @_; my $self = {}; return bless $self, $class; } =head2 clear Deletes all the extent parameters. Does not return anything. $thingy->clear(); =cut sub clear { my ($self) = @_; foreach my $param ( keys %{$self} ) { delete $self->{$param}; } return; } =head2 clone Returns a new L<Object::WithParams> with the same set of parameters as + the old one. my $doodad = $thingy->clone(); =cut sub clone { my ($self) = @_; my $clone = Object::WithParams->new(); foreach my $param ( $self->param() ) { $clone->param( $param => $self->param($param) ); } return $clone; } =head2 delete Delete the named parameter. $thingy->delete('veggie'); =cut sub delete { ## no critic 'Subroutines::ProhibitBuiltinHomonyms' my ( $self, $param ) = @_; if ( defined $param && exists $self->{$param} ) { delete $self->{$param}; } return; } =head2 param The C<param> method can be called in three ways. =over 4 =item with no arguments. Returns a list of the parameters contained in the object. my @params = $thingy->param(); =item with a single scalar argument. The value of the parameter with the name of the argument will be retur +ned. my $color = $thingy->param('color'); =item with named arguments A parameter is created for one or more sets of keys and values. $thingy->param(filename => 'logo.jpg', height => 50, width => 100); You could also use a hashref. my $arg_ref = { filename => 'logo.jpg', height => 50, width => 100 }; $thingy->param($arg_ref); The value of a parameter need not be a scalar, it could be any any sor +t of reference even a coderef. $thingy->param(number => &pick_a_random_number); Does not return anything. =back =cut sub param { my ( $self, @args ) = @_; my $num_args = scalar @args; if ($num_args) { if ( ref $args[0] eq 'HASH' ) { # a hashref %{$self} = ( %{$self}, %{ $args[0] } ); } elsif ( $num_args % 2 == 0 ) { # a hash %{$self} = ( %{$self}, @args ); } elsif ( $num_args == 1 ) { # a scalar return $self->{ $args[0] }; } else { croak('Odd number of arguments passed to param().'); } } else { return keys %{$self}; } return; } 1;

        What do you think? I can finish writing the tests and put it up on on CPAN if it is of interest.

        --
        જલધર

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://854059]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (16)
As of 2015-01-30 16:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My top resolution in 2015 is:

















    Results (252 votes), past polls