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

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

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 ]

8 голосов
/ 20 апреля 2010

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

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

 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 { ... }

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

4 голосов
/ 20 апреля 2010

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

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

3 голосов
/ 20 апреля 2010

Вы вообще не наследуете 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 (документация говорит, что он устарел, так что это большой красный флаг, если вы все еще хотите использовать его, не разбираясь в его механике).

0 голосов
/ 25 августа 2014
        # 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
...