in reply to Typeglobs and Symbol tables

Thanks for all of the help, everyone! Here's the new list_params() function:

sub list_params { my ( $self, $cgi ) = @_; my %formdata; $cgi = CGI::self_or_default if ( ! defined $cgi or ! ref $cgi ) an +d $cgi; if ( defined $cgi and $cgi ) { foreach my $key ( $cgi->param ) { my @vals = $cgi->param( $key ); $formdata{ $key } = _format_vals( \@vals ); } } else { return 0; } Dumper( \%formdata ); }

It's smaller, cleaner, faster, and no typeglobs. I've tested it fairly carefully from the command line and it seems to be fine, regardless of the number of CGI objects or mixing and matching the function and object-oriented interfaces.

Wondering one thing, though: if a object is a subclass of CGI.pm. is it possible for it to not have the param() method? If so, I'll need to test for $cgi->can('param'). If it is possible to inherit from a module but not inherit all methods, how would that be done?

Cheers,
Ovid

Update: Updated code to be even cleaner.

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Replies are listed 'Best First'.
Re: (Ovid - Dang, I love this place -- and one more question :)
by mirod (Canon) on Jun 01, 2001 at 21:21 UTC

    It might be hard not to inherit the param method, but it is certainly possible to redefine it so its return values make no sense for you:

    package my_dumb_cgi; @ISA = ("CGI"); sub param { return "gotcha!"; }

    Not that this would make any sense, just that it is possible.

(tye)Re: (Ovid - Dang, I love this place -- and one more question :)
by tye (Sage) on Jun 01, 2001 at 23:27 UTC

    Ah, better. This:

    params { my ( $self, $cgi ) = @_; my %formdata; $cgi = CGI::self_or_default if ( ! defined $cgi or ! ref $cgi ) an +d $cgi; if ( defined $cgi and $cgi ) {
    deserves a bit of "improvement". I'll go through step-wise as I hope that will be more enlightening.

    I was not able to understand this:     $cgi = CGI::self_or_default if ( ! defined $cgi or ! ref $cgi ) and $cgi; so I did some "mechanical" translation which made it easy for me to understand (this may have more to do with the strange ways in which my mind works, though):     $cgi = CGI::self_or_default   if  $cgi  and  ! ( defined $cgi and ref $cgi ); So we don't want to override $cgi if it is false and we don't want to override $cgi if it is a good reference. But, my testing shows that ref $cgi doesn't produce a warning even if $cgi is undef so we can shorten this to:     $cgi = CGI::self_or_default   if  $cgi  and  ! ref $cgi;

    Similarly, $cgi in a "Boolean context" doesn't elicit a warning in the face of undef so:     if ( defined $cgi and $cgi ) { can become:     if (  $cgi  ) {

    This brings us to:

    params { my ( $self, $cgi ) = @_; my %formdata; $cgi = CGI::self_or_default if $cgi and ! ref $cgi; if ( $cgi ) {
    But I'd factor out the if($cgi):
    if ( $cgi ) { $cgi = CGI::self_or_default if ! ref $cgi;
    Finally you can swap if ! with just unless, but I find that mostly a matter of taste.

    Well, anyway, that "works" better for me. (:

            - tye (but my friends call me "Tye")

      Much nicer. One little issue, though:

      # This: $cgi = CGI::self_or_default if $cgi and ! ref $cgi; # is not equivalent to this: $cgi = CGI::self_or_default if ! ref $cgi;

      The reason this is the case is how it's called:

      print $foo->list_params( 1 );

      If someone supplies a false value, it should return "0". With the second version of your assignment to $cgi, it will always return the params, regardless of whether or not a false value has been passed. That might seem irrelevant, but this is a reduced test case of the actual code. Here's how this will be used in real life:

      $write->table( -params => 1, -condition => "$x % 7 == 3", -active => 1, -caller => 0, SomeVar => $some_var, DATA => \%some_hash );

      Since this is part of a debugging module, the programmer may want to turn off the param display once the params are verified, or turn them back on again if there is a problem. Rather than going through and deleting or re-entering the '-param' key, the programmer can just toggle the value at will. (I know we discussed this with /msgs, but this is for the benefit of those not privy to the conversation).

      Cheers,
      Ovid

      Update: Hmm... I seem to be posting a lot of updates lately :(

      Seems I missed a little if which drastically changes the meaning of tye's code:

      if ( $cgi ) { $cgi = CGI::self_or_default if ! ref $cgi;

      sigh

      Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: (Ovid - Dang, I love this place!) Re: Typeglobs and Symbol tables
by bikeNomad (Priest) on Jun 01, 2001 at 21:05 UTC
    Ovid asks: Wondering one thing, though: if a object is a subclass of CGI.pm. is it possible for it to not have the param() method? If so, I'll need to test for $cgi->can('param'). If it is possible to inherit from a module but not inherit all methods, how would that be done?

    First I figured you could undef a subroutine:

    package MyCGI; use base CGI; undef(*MyCGI::param);
    But then I realized that the subroutine wasn't defined in MyCGI, it was defined in CGI. So I don't think you can undef an inherited routine. But I'm not sure...

    Update: would it be possible to (instead of using @ISA for inheritance) copy all of the subroutine refs from the parent class symbol table into your own and then delete one of them? I'll look into it...

    Later: yes, you can copy from a superclass instead of using @ISA:

    package A; sub abc { "abc\n" }; sub def { "def\n" }; package B; # inherit from A all but A::def foreach my $symname (keys %A::) { next if $symname eq 'def'; $B::{$symname} = $A::{$symname}; } my $b = bless({}, 'B'); print $b->abc; # prints "abc\n" print $b->def; # no such method