: -----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/