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

发布于 2024-08-29 07:44:54 字数 836 浏览 9 评论 0原文

我有一个像这样的基类:

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

}

我想像调用原始 MyClass 一样调用此 MySubclass,并且仍然可以访问 Exporter 中的所有变量和函数。但是,我在从原始类 MyClass 获取 Exporter 变量以正确导出时遇到问题。我需要在子类中再次运行 Exporter 吗?这似乎多余且不清楚。

示例文件:

#!/usr/bin/perl

use MySubclass qw/$ME/;

-- rest of code

但是当我尝试导入 $ME 变量时出现编译错误。有什么建议吗?

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.

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. However I am having problems getting the Exporter variables from the original class, MyClass, to export correctly. Do I need to run Exporter again inside the subclass? 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. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

绮筵 2024-09-05 07:44:54

您应该通过方法访问所有内容。忘记传递变量。

您收到语法错误是因为您有语法错误:

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

如果您有许多需要共享的变量,则有各种模块可以自动为您处理访问器详细信息。

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:

 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.

奶茶白久 2024-09-05 07:44:54

一般来说,OO Perl 和 Exporter 通常是分开的,而不是混合在一起。这就是原因之一。

就像布莱恩说的,如果你把你导出的所有垃圾都拿出来,把它变成类属性/方法,然后摆脱它,你会更容易地让它工作起来,并在未来进一步扩展它。完全属于出口商。一个简单的事实是,您想要的方式需要您导入和重新导出所有内容,这应该是一个巨大的、闪烁的线索,表明可能有更好的方法来做到这一点(即,一种不涉及 Exporter 的方式)。

In general, OO Perl and Exporter are normally kept separate instead of mixing them together. 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 (i.e., a way that doesn't involve Exporter).

韬韬不绝 2024-09-05 07:44:54

您实际上根本没有从 MyClass 继承 MySubclass -- MySubClassMyClass 的用户 。您正在做的是覆盖 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文档说它是已过时,因此如果您仍然想在不了解其机制的情况下使用它,那么这是一个很大的危险信号)。

You're not actually inheriting MySubclass from MyClass at all -- MySubClass is a user of MyClass. 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.

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:

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

羁〃客ぐ 2024-09-05 07:44:54
        # 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
        # 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文