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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.