Как я могу разделить переменные между базовым классом и подклассом в Perl?

У меня есть базовый класс, как это:

package MyClass;

use vars qw/$ME list of vars/;
use Exporter;
@ISA = qw/Exporter/;
@EXPORT_OK = qw/ many variables & functions/;
%EXPORT_TAGS = (all => \@EXPORT_OK );

sub my_method {

}
sub other_methods etc {

}

--- more code---

Я хочу подкласс MyClass, но только для одного метода.

package MySubclass;

use MyClass;
use vars qw/@ISA/;
@ISA = 'MyClass';

sub my_method {

--- new method

}

И я хочу назвать это MySubclass как я бы оригинал MyClassи по-прежнему иметь доступ ко всем переменным и функциям из Exporter, Однако у меня проблемы с получением Exporter переменные из исходного класса, MyClass, правильно экспортировать. Мне нужно бежать Exporter снова внутри подкласса? Это кажется излишним и неясным.

Пример файла:

#!/usr/bin/perl

use MySubclass qw/$ME/;

-- rest of code

Но я получаю ошибки компиляции, когда я пытаюсь импортировать $ME переменная. Какие-либо предложения?

4 ответа

Решение

Вы на самом деле не наследуете MySubclass от MyClass совсем -- MySubClass пользователь MyClass, То, что вы делаете, это переопределение немного поведения от MyClass, но вы только запутаете себя, если будете думать об этом как о наследовании, потому что это не так (например, где находится ваш конструктор?). Я не мог понять, что вы пытались сделать, пока не проигнорировал все, что делал код. и просто прочитайте ваше описание того, что вы хотите, чтобы произошло.

Итак, у вас есть класс, который импортирует некоторые символы - некоторые функции и некоторые переменные:

package MyClass;
use strict;
use warnings;

use Exporter 'import';    # gives you Exporter's import() method directly
our @EXPORT_OK = qw/ many variables & functions/;
our %EXPORT_TAGS = (all => \@EXPORT_OK );
our ($ME, $list, $of, $vars);

sub my_func {

}
sub other_func {

}
1;

а затем вы приходите и пишете класс, который импортирует все из MyClass, снова импортирует все это обратно, но заменяет одну функцию на другую:

package MyBetterclass;
use strict;
use warnings;
use Exporter 'import';    # gives you Exporter's import() method directly
our @EXPORT_OK = qw/ many variables & functions /;
our %EXPORT_TAGS = (all => \@EXPORT_OK );
use MyClass ':all';

sub my_func {
    # new definition   
}
1;

Это оно! Обратите внимание, что я включил строгую проверку и предупреждения и изменил имена "методов", которые на самом деле являются функциями. Кроме того, я не использовал use vars ( документация говорит, что он устарел, так что это большой красный флаг, если вы все еще хотите использовать его, не понимая его механику).

Вы должны получить доступ ко всему через методы. Забудьте о передаче переменных вокруг.

Вы получаете синтаксическую ошибку, потому что у вас есть синтаксическая ошибка:

 use MySubclass /$ME/; # syntax error - that's the match operator

Вы хотите список там:

 use MySubclass qw/$ME/;

Однако не делайте этого. Обеспечить доступ к этим данным через методы. Поскольку вы наследуете методы, вам не нужен (и не должен использоваться) экспортер:

 package MyClass;

 BEGIN {
 my $ME;
 sub get_me { $ME }
 sub set_me { $ME = shift }
 }

Теперь ваш подкласс просто:

 package MySubclass;
 use parent( MyClass );
 sub my_method { ... }

Существуют различные модули, которые могут автоматически обрабатывать детали доступа для вас, если у вас есть много переменных, которыми вы хотите поделиться.

В общем, OO Perl и Exporter обычно хранятся отдельно, а не смешиваются вместе. Это одна из причин, почему.

Как сказал Брайан, вам будет гораздо проще начать работать с этим в первую очередь и расширять его в будущем, если вы возьмете все экспортируемое дерьмо, превратите его в свойства / методы класса и избавитесь от него. экспортера полностью. Простой факт, что способ, которым вы хотите это сделать, требует, чтобы вы импортировали и реэкспортировали все, должен быть большой, вспыхивающей подсказкой, что, вероятно, есть лучший способ сделать это (то есть способ, который не использует Exporter).

        # use setters and getters the Perl's way 
        #
        # ---------------------------------------
        # return a field's value
        # ---------------------------------------
        sub get {

            my $self = shift;
            my $name = shift;
            return $self->{ $name };
        }    #eof sub get


        #
        # ---------------------------------------
        # set a field's value
        # ---------------------------------------
        sub set {

            my $self  = shift;
            my $name  = shift;
            my $value = shift;
            $self->{ $name } = $value;
        }
        #eof sub set


        #
        # ---------------------------------------
        # return the fields of this obj instance
        # ---------------------------------------
        sub dumpFields {
            my $self = shift;

            my $strFields = ();
            foreach my $key ( keys %$self ) {
                $strFields .= "$key = $self->{$key}\n";
            }

            return $strFields;
        }    #eof sub dumpFields
Другие вопросы по тегам