Working more on my debugging module and I wanted a cleaner interface for dumping CGI params than the dumping the CGI object. Basically, I'd like the user to be able to get a list of all parameters and their associated values. However, I want them to be able to do this regardless of whether or not they are using the function oriented or object oriented methods of CGI.pm. Here's some code that demonstrates:
use strict; use warnings; use Foo; use CGI qw/:standard/; my $q = CGI->new( { foo => 'bar', baz => 'Ovid' } ); my $foo = Foo->new; print $foo->list_params( 1 ); print $foo->list_params( $q );
The object takes its parameters from the ones passed to the constructor. Running this from the command line will give the function oriented method the parameters entered on the command line. Name the program test.pl and enter the following from the command line:
test.pl one=two red=blue red=herring bob= marley=bob
The output should be as follows:
$VAR1 = { 'one' => 'two', 'red' => [ 'blue', 'herring' ], 'marley' => 'bob', 'bob' => '' }; $VAR1 = { 'foo' => 'bar', 'baz' => 'Ovid' };
Here's the module Foo.pm that creates this output (this is all simplified tremendously):
package Foo; use strict; use Data::Dumper; sub new { my $class = shift; my ( $package ) = caller; my $objref = { _package => $package }; bless $objref, $class; } sub list_params { my ( $self, $cgi ) = @_; my %formdata; # Use this if OO CGI if ( ref $cgi eq 'CGI' ) { foreach my $key ( $cgi->param ) { my @vals = $cgi->param( $key ); $formdata{ $key } = _format_vals( \@vals ); } # Function-oriented CGI } elsif ( $cgi ) { { # Don't try this at home, kids no strict qw/ refs subs /; my $_param = $self->{ '_package' }.'::param'; my $package = \%{$self->{ '_package' } . '::'}; # Looks like a function oriented call but 'param' was not +exported if ( ! exists $package->{ 'param' } ) { return 0; } foreach my $key ( eval $_param ) { my $_param_call = $_param . "($key)"; my @vals = eval $_param_call; $formdata{ $key } = _format_vals( \@vals ); } } } else { return 0; } Dumper( \%formdata ); } sub _format_vals { my $vals = shift; @$vals == 1 ? @$vals[ 0 ] : ! @$vals ? undef : $vals; } "Ovid";
My first question: I don't like the fact that the user has two different ways of calling the method depending upon whether or not they are using the function or object oriented interface to CGI.pm. Unfortunately, I can't think of a way to simplify this. I would prefer for this to be transparent. I suppose I could walk the symbol table of the calling package and pick any object with a CGI ref, but what if they have more than one CGI object instantiated?
My second question: I've not used typeglobs a lot. Are there any issues with this that I should be aware of?
Third question: I have read several times that taking the ref of an object to determine what it is can be a bad idea. Is it possible that the user could pass a valid CGI object that won't have a ref of 'CGI'?
Fourth question: Is there a cleaner way to write the "no strict..." block in Foo.pm?
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.
In reply to Typeglobs and Symbol tables by Ovid
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |