Reputation: 63932
Have this demo CGI script (cgi_script.pl
)
use 5.014;
use warnings;
use CGI;
my $q = CGI->new();
say $q->h1( join '-', $q->multi_param('p') );
say CGI::h1('some other');
runing it as perl cgi_script.pl p=1 p=2
prints
<h1>1-2</h1>
<h1>some other</h1>
I want create My::CGI
and it should do exactly everything as CGI
does. For now I have:
package My::CGI;
use 5.014;
use warnings;
use base qw(CGI);
1;
And modify the above script (my_script.pl
)
use 5.014;
use warnings;
use My::CGI;
my $q = My::CGI->new();
say $q->h1( join '-', $q->multi_param('p') );
say My::CGI::h1('some other');
when running it as perl my_script.pl p=1 p=2
it prints:
<h1>1-2</h1>
Undefined subroutine &My::CGI::h1 called at my_script.pl line 7.
e.g., the object oriented interface works, but not the functions, like CGI::h1(...)
and such.
The question is: How to create the My::CGI
to be fully compatible with the parent CGI
? e.g.
My::CGI::h1(...)
... etcuse My::CGI qw(:xxx)
#xxx from the CGI, e.g. :all
or :html2
and etc...Not need code, just any pointer/idea to "how to solve correctly" the problem.
Upvotes: 0
Views: 135
Reputation: 241918
Fortunately, CGI supports the :all
tag:
#! /usr/bin/perl
use warnings;
use strict;
{ package MyCGI;
use CGI qw{ :all }; # Import all functions.
use parent 'CGI'; # Inherit the methods.
}
my $q = MyCGI->new;
print $q->h1('Title');
print MyCGI::h2('Section');
Upvotes: 3
Reputation: 54333
You basically gave the basis for an answer yourself. You are talking about sub_classing_. A class implies an object. Calling the functional interface of a module that provides both functional and object oriented interfaces will need extra work when inheriting.
Perl's object orientation has a few pitfalls. In general it works with the package namespaces. There is CGI
, and there is My::CGI
. If you say
package My::CGI;
use base 'CGI';
or
package My::CGI;
use parent 'CGI';
you tell Perl that anything that is blessed into the My::CGI namespace has CGI in its @ISA
. That's the inheritance thingy.
But if you call a simple function (not a method), that is ignored. There is just the namespace.
package My::CGI;
use 5.014;
use warnings;
use base qw(CGI);
1;
This package does not define any subs in its namespace. So you cannot call them. They are still located only in the CGI package.
You would have get them into your own namespace first.
package My::CGI;
use 5.014;
use warnings;
use base qw(CGI);
*h1 = \&CGI::h1;
1;
Now your example call will work.
Of course that is a bit tedious. You could look into the symbol table, check out the entries and work with those to automatically create aliases for all the functional interface subs.
Upvotes: 1