: -----Original Message-----
: From: owner-cgi-list@jann.com [mailto:owner-cgi-list@jann.com]
: On Behalf Of Vuillemot, Ward W
: Sent: Thursday, February 28, 2002 10:28 AM
: To: cGI LIST
: Subject: [CGI] OT: Sub-classing a method
:
:
: Anyone know the best way to overwrite a method from one module
: with another?
I'm sure there is, but I'll have a go anyway...
: In particular, I am trying to write my modules to run in both mod_cgi or
: mod_perl space. If mod_cgi space then I want to use CGI.pm to read in the
: querystring, et cetera. If mod_perl then I want to use Apache::Request.
: Both have the param() method. However, I sometimes use CGI.pm to
: generate HTML. Which makes things a bit difficult.
I follow.
: At the moment all my apps run a config() method that loads a
: reference to an
: instance of CGI.pm. The easiest way to get things working is to determine
: if I am running under mod_perl or not. If not, then nothing changes. If
: so, then when I do something like
: $self->{query}->param('formVariable') if will
: use Apache::Request->param() versus CGI->param().
:
: (BTW, $self->{query} is the reference I was mentioning -- though I
: typically
: set that to a locally scoped variable such as $q with a
: subroutine. SO, the
: code might really look like $q->param('formVariable'), but anyway.)
:
: I believe this is called sub-classing. . .but I have never done it.
: I have done inheritance and over-ridden the parent's subroutine by the
: same name.
Subclassing is the act of making one's module a subclass to another.
(ok, duh --so what does that mean?) If you make a module called
CGI::ward_sbclass you've subclass-ed CGI.pm Technically that is all
you have to do. That was hard huh? Even if you do not explicitly
state that you are going to import/inherit from CGI [more on this
later], you can still access it's namespace via
$CGI::ward_sbclass:SUPER which is a special pointer that Perl assigns
to subclasses of a parent class.
Really though, you should be a good little subclass and inherit your
parent class' methods and attributes (subroutines and variables) in
order to be a true "chip off the ol' block". No apple wants to fall
too far from the tree! Otherwise, subclassing is pointless. In order
to inherit your parent class' methods and attributes, in
ward_sbclass.pm you just specify that:
@CGI::ward_sbclass::ISA = qw(CGI);
...and bingo! CGI::ward_sbclass is not only a CGI::ward_sbclass, but is
also now a CGI! Think of it like the day you were born. You received
your very own name. But you were still a 'subclass' of your parents.
As such, you also carry their name. If you were a module, you could
rightly be named--
Vuillemot::Ward
and naturally you will have your own unique characteristics, behaviors,
and different ways of doing things, but try as you may, you'll always
be a Vuillemot. You will still have your daddy's nose, your mommy's
toes, and you'll probably carry a similar inflection in your speech,
gait in your step, gesticulation in movement, opinions in politics,
beliefs in religion, etc.
OO is the same.
: .but I want to do is say this hash element is a reference to CGI.
: Through this reference I can call all of CGI.pm methods. HOWEVER, if I
: am running in mod_perl then all of CGI.pm methods still are applicable
: with the exception of param() which will instead be Apache::Request
: param() method.
Well, Ward, from the beginning of your post you've really been asking
not how to subclass a module, but how to customize it. In order to do
that, you have to either break into it's namespace, or inherit from
your parent class and redefine the method you need in such a way that
it does as you like. Sometimes either is a good choice, but in the
Perl community at large, "don't walk in on your parents". "Stay out
of their space" --if you follow me. Basically, you don't need to break
in and screw around with a parent class' stuff unless you have
permission, or no one is looking and you're the only one who'll ever
use the module.
How to break in:
# Ok, so lets pretend we're inside CGI::ward_sbclass.
# Now if we want to break into CGI's class without permission
# and have some fun jumping on the bed, we do this.
package CGI;
# Viola! you are now Lincoln Stein and you can write CGI.pm
# any way you want. Let's have a try:
sub param {
return(q[the joke's on you! HA-HA-HA-HA-HA!]);
}
# now any time you call CGI::param() you'll always get the
# unpleasant surprise. Can you believe that?!? Way cool.
# Funny, I feel like I just taught someone how to make a bomb...
: Ideas? I want to be lazy. . .am I just being TOO lazy?
Try something like this...
package Wardwrapper;
use Apache::Request;
use CGI;
$Wardwrapper::apachebaby = {};
$Wardwrapper::cgibaby = {};
$Wardwrapper::apachebaby = Apache::Request->new();
$Wardwrapper::cgibaby = CGI->new();
$Wardwrapper::apacheparamref = sub { Apache::Request->param(@_) };
$Wardwrapper::cgiparamref = sub { $Wardwrapper::cgibaby->param(@_) };
# used here only for demonstrational purposes
$Wardwrapper::cgiheaderref = sub { $Wardwrapper::cgibaby->header() };
sub new {
my($class) = shift;
my($this) = {};
bless($this, $class);
return($this);
}
sub cgiparam {
return(&$Wardwrapper::cgiparamref);
}
sub apacheparam {
return(&$Wardwrapper::apacheparamref);
}
sub cgiheader {
return(&$Wardwrapper::cgiheaderref);
}
package main;
my($ww) = Wardwrapper->new();
my(@cgiparams) = $ww->cgiparam();
print(join(qq[\n\n],@cgiparams));
print($ww->cgiheader());
# or even...
print $ww->{'cgibaby'}->version();
Cool. I'm out.
-Tommy Butler, consultant
Atrixnet, for Internet Business Software
http://atrixnet.com
2200 North Lamar
Suite 307
Dallas, TX
75202
--
I need work!
http://www.atrixnet.com/contracting/
Request a script!
mailto:gimmecode@atrixnet.com
Get help with code!
mailto:helpme@atrixnet.com
Get my resume!
http://www.atrixnet.com/resume/
Visit the open source Perl archives at Atrixnet.
http://www.atrixnet.com/pub/