如何创建子模块?

时间:2013-05-20 21:34:34

标签: perl

我已经离开了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

3 个答案:

答案 0 :(得分: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. new上的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()来调用该方法。

答案 1 :(得分: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一个很好的起点。

答案 2 :(得分:1)

您的孩子班(use base

中缺少package WWW::Foo::Bar
use base qw(WWW::Foo);