2015-12-11 3 views
0

Имейте это демо CGI скрипт (cgi_script.pl)Как подклас CGI.pm быть полностью работоспособным?

use 5.014; 
use warnings; 
use CGI; 
my $q = CGI->new(); 
say $q->h1(join '-', $q->multi_param('p')); 
say CGI::h1('some other'); 

подножка это как perl cgi_script.pl p=1 p=2 отпечатков

<h1>1-2</h1> 
<h1>some other</h1> 

Я хочу создать My::CGI и он должен делать именно все, как CGI делает. На данный момент у меня есть:

package My::CGI; 
use 5.014; 
use warnings; 
use base qw(CGI); 
1; 

И изменить приведенный выше сценарий (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'); 

при работе как perl my_script.pl p=1 p=2 она печатает:

<h1>1-2</h1> 
Undefined subroutine &My::CGI::h1 called at my_script.pl line 7. 

например, объектно-ориентированный интерфейс работает, но не функции, такие как CGI::h1(...) и т. д.

Вопрос: Как создать My::CGI для полной совместимости с родителем CGI? например

  • для получения рабочего функционального интерфейса, например. My::CGI::h1(...) ... и т.д.
  • , а также получить рабочий use My::CGI qw(:xxx) #xxx от CGI, например. :all или :html2 и т.д ...

не нужен код, просто любой указатель/идея «как правильно решить» проблему.

+0

смешанный режим (ОО + функциональный) модуль интерфейсы опале в сообществе Perl некоторое время теперь, и вы видите, одна из причин, почему , Чтобы «наследовать» функциональный интерфейс модуля OO в ваш подкласс, вам необходимо полностью охватить загрязнение пространства имен. – tjd

ответ

3

К счастью, CGI поддерживает :all тег:

#! /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'); 
+0

ДА! Отлично, спасибо. – Nemo

+0

Очевидно, что это более короткая версия. :) – simbabque

1

Вы в основном дали основу для ответа самостоятельно. Вы говорите о sub_classing_. A класс подразумевает объект . Вызов функционального интерфейса модуля, который обеспечивает функциональные и объектно-ориентированные интерфейсы, потребует дополнительной работы при наследовании.

Объектная ориентация Perl имеет несколько подводных камней. В общем, он работает с пространствами имен пакетов. Существует CGI, и есть My::CGI. Если вы говорите,

package My::CGI; 
use base 'CGI'; 

или

package My::CGI; 
use parent 'CGI'; 

вы сказать Perl, что все, что благословляется в Мой :: CGI имен имеет CGI в @ISA. Это наследование.

Но если вы вызываете простую функцию (а не метод), это игнорируется. Существует просто пространство имен.

package My::CGI; 
use 5.014; 
use warnings; 
use base qw(CGI); 
1; 

Этот пакет не определяет подсемейки в своем пространстве имён. Поэтому вы не можете их назвать. Они все еще находятся только в пакете CGI.

Сначала вы должны были бы получить их в своем собственном пространстве имен.

package My::CGI; 
use 5.014; 
use warnings; 
use base qw(CGI); 

*h1 = \&CGI::h1; 

1; 

Теперь ваш пример вызова будет работать.

Конечно, это немного утомительно. Вы можете заглянуть в таблицу символов, проверить записи и работать с ними, чтобы автоматически создавать псевдонимы для всех интерфейсов функционального интерфейса.

+0

Итак, если я понимаю правильно - в основном нужно наложить псевдоним '* sub' всех функций, которые находятся в [CGI.pm] (https://metacpan.org/source/LEEJO/CGI-4.22/lib/CGI.pm) ' s '% EXPORT_TAGS'. И, вероятно, нужно создать свои собственные ЭКСПОРТЫ. – Nemo

+0

@ Нет, да, это в значительной степени. – simbabque

Смежные вопросы