2

我离开 Perl 世界太久了。我想创建一个子模块并访问它的功能。我基本上只是想念如何连接这些并访问这些方法。

父示例:WWW::Foo

package WWW::Foo
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw( new ) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw( );
our $VERSION = '0.01';

sub new {
    my ($package) = @_;

    $package::account_name = "Paul";
    return bless({}, $package);
}

子示例:WWW::Foo::Bar

package WWW::Foo::Bar
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw( new ) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw( );
our $VERSION = '0.01';

sub print_name {
    my ($package) = @_;
    # Access parent's package and do basic print.
    return;
}

示例脚本

#!/usr/bin/perl -w
use strict;
use WWW::Foo;
use WWW::Foo::Bar;

my $foo = new WWW::Foo();
# Access WWW::Foo::Bar's print_name function
4

3 回答 3

5

这是一个简短的工作示例。

use strict;
package WWW::Foo;

sub new {
    my ($package) = @_;
    my $self = bless {}, $package;
    $self->{account_name} = "Paul";
    return $self;
}


package WWW::Foo::Bar;
use base "WWW::Foo";

sub print_name {
    my ($self) = @_;
    my $name = $self->{account_name};
    print "Hello $name\n";
}


package main;
my $foo = WWW::Foo::Bar->new();
$foo->print_name();

以下是发生的变化:

  1. 我已经删除了Exporter. 这里没有必要——包中定义的所有方法都可以通过名称调用而无需涉及。

  2. newon 方法在它正在创建的对象上设置WWW::Foo一个account_name键,而不是在包本身上。(在包上设置它意味着所有对象在这里都具有相同的值,使它们相当无用。)

  3. WWW::Foo::Bar对象现在使用base包继承自WWW::Foo.

  4. WWW::Foo::Bar::print_name方法现已充实。我们可以访问account_name对象上的键来获取名称。(这也可以写成单行print "Hello $self->{account_name}\n",但这会不太清楚。)

  5. main被声明。(这只是为了简单。如果您在自己的文件中编写每个包,则不需要它。)

  6. 我们实例化WWW::Foo::Bar而不是WWW::Foo,因为我们需要在子类上定义的方法。(如果我们实例化了父类WWW::Foo,它就不会支持这种方法。)

  7. 我们不使用间接方法调用new。间接方法调用很糟糕。

  8. 我们调用$foo->print_name()调用方法。

于 2013-05-20T21:46:00.637 回答
4

您的“子”示例包括以下行:

our %EXPORT_TAGS = ( 'all' => [ qw( new ) ] );

这将导出一个名为“new”的函数,并且不会导出任何其他函数(例如:)print_name

然而,导出函数有点“老派”,而且我几乎不再在我的 Perl 代码中做这件事了。特别是,如果您正在编写面向对象的代码(您似乎是),则不需要导出任何内容,因为构造函数将通过类名显式调用,而所有其他方法都通过对象调用,所以Perl 知道在哪个包中找到它们。

你这样调用你的构造函数:

my $foo = new WWW::Foo();

最好的做法是避免使用“间接对象语法”,而是显式调用 new 作为类方法,如下所示:

my $foo = WWW::Foo->new();

如果您已经离开 Perl 一段时间并想做 OO 代码,我真的建议您看看 Moose。 Moose::Manual是一个很好的起点。

于 2013-05-20T21:51:19.080 回答
1

你只是use base在你的孩子班里失踪了(package WWW::Foo::Bar

use base qw(WWW::Foo);
于 2013-05-20T21:45:53.537 回答