简体   繁体   English

如何在Perl中的基类和子类之间共享变量?

[英]How can I share variables between a base class and subclass in Perl?

I have a base class like this: 我有这样一个基类:

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

I want to subclass MyClass , but only for one method. 我想MyClass ,但仅限于一种方法。

package MySubclass;

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

sub my_method {

--- new method

}

And I want to call this MySubclass like I would the original MyClass , and still have access to all of the variables and functions from Exporter . 我想把这个MySubclass称为原始MyClass ,并且仍然可以访问Exporter所有变量和函数。 However I am having problems getting the Exporter variables from the original class, MyClass , to export correctly. 但是我在从原始类MyClass获取Exporter变量时遇到问题,无法正确导出。 Do I need to run Exporter again inside the subclass? 我是否需要在子类中再次运行Exporter That seems redundant and unclear. 这似乎多余而且不清楚。

Example file: 示例文件:

#!/usr/bin/perl

use MySubclass qw/$ME/;

-- rest of code

But I get compile errors when I try to import the $ME variable. 但是当我尝试导入$ME变量时,我遇到了编译错误。 Any suggestions? 有什么建议么?

You should access everything through methods. 您应该通过方法访问所有内容。 Forget about passing variables around. 忘记传递变量。

You're getting a syntax error because you have a syntax error: 您收到语法错误,因为您有语法错误:

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

You want a list there: 你想要一个清单:

 use MySubclass qw/$ME/;

However, don't do that. 但是,不要这样做。 Provide access to these data through methods. 通过方法提供对这些数据的访问。 Since you'll inherit the methods, you don't need (and shouldn't use) Exporter: 由于您将继承这些方法,因此您不需要(也不应该使用)Exporter:

 package MyClass;

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

Now your subclass is just: 现在您的子类只是:

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

There are various modules that can automatically handle the accessor details for you if you have many variables you need to share. 如果您需要共享许多变量,有各种模块可以自动处理访问者详细信息。

In general, OO Perl and Exporter are normally kept separate instead of mixing them together. 通常,OO Perl和Exporter通常是分开的,而不是将它们混合在一起。 This is one of the reasons why. 这是其中一个原因。

Like brian said, you'll have a much easier time getting this to work in the first place and with extending it further in the future if you take all the crap you're exporting, turn it into class properties/methods, and get rid of Exporter completely. 就像布莱恩所说的那样,如果你拿出你要导出的所有废话,将它转换为类属性/方法,并摆脱它,你将会更容易在第一时间开始工作并进一步扩展它。出口商完全。 The simple fact that the way you want to do it requires you to import and re-export everything should be a big, flashing clue that there's probably a better way to do it (ie, a way that doesn't involve Exporter). 一个简单的事实,你想要它的方式要求你导入和重新导出一切应该是一个很大的,闪烁的线索,这可能是一个更好的方法(即,一种不涉及出口商的方式)。

You're not actually inheriting MySubclass from MyClass at all -- MySubClass is a user of MyClass . 你实际上并MySubclassMyClass继承MySubclass - MySubClassMyClass 的用户 What you're doing is overriding a bit of behaviour from MyClass , but you will only confuse yourself if you think of this as inheritance, because it isn't (for example: where is your constructor?) I couldn't figure out what you were trying to do until I ignored everything the code was doing and just read your description of what you want to have happen. 你正在做的是覆盖MyClass的一些行为,但如果你认为这是继承,你只会混淆自己,因为它不是(例如:你的构造函数在哪里?)我无法弄清楚是什么你试图做,直到我忽略了代码所做的一切,只是阅读你想要发生的事情的描述。

Okay, so you have a class which imports some symbols - some functions, and some variables: 好的,所以你有一个导入一些符号的类 - 一些函数和一些变量:

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;

and then you come along and write a class which imports everything from MyClass, imports it all back out again, but swaps out one function for another one: 然后你来写一个从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;

That's it! 而已! Note that I enabled strict checking and warnings, and changed the names of the "methods" that are actually functions. 请注意,我启用了严格的检查和警告,并更改了实际功能的“方法”的名称。 Additionally, I did not use use vars (the documentation says it's obsolete, so that's a big red flag if you still want to use it without understanding its mechanics). 另外,我没有使用use vars文档说它已经过时了,所以如果你还想在不了解它的机制的情况下使用它,那将是一个很大的危险信号)。

        # 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM