Perl:使用parent更改模块的某些方法

时间:2013-07-09 00:22:23

标签: perl

想象一下,我有一个CPAN-ish模块,我不能让自己直接修改 Module :: Cool,其方法有new,communic_heartbeat,is_running,remove_heartbeat和prefix。

我想使用这些方法,但我需要稍微更改“前缀”方法。 我听说你可以在本地,服务器等创建一个文件,如:

package My::Module::Cool;               

use strict;                              
use warnings;                            
use utf8;                                

use parent qw(Module::Cool);                                                                                                        

1; 

如果我在这里添加一个“子前缀{....}”方法,当我尝试使用My :: Module :: Cool时,将使用“prefix”方法,我写的新的或原来的来自父模块?

4 个答案:

答案 0 :(得分:4)

如果这些方法是函数(注意:不是类的一部分,而不是你已经完成的事情my $instance = Module::Cool->new();它不会做你想要的。由父模块导出到你的模块的子程序不会因为'parent'模块仅用于扩展对象,所以可以导入到你的命名空间(故意 - 它会破坏OO)。如果这些子例程碰巧有类似OO的名称,{{1} (用于导出函数的模块)可以解决问题。

首先,您必须将您想要的其他功能带入您的模块(带导入 - 这是use parent在导出子程序时在幕后所做的事情),构建您自己的替换函数(调用原始函数)如果需要),再次出口一切。

以下是一个例子:

Exporter

如果use Cool::Module未自动导出,请与use strict; use warnings; use utf8; # Make sure this happens at compile time, before anything else in the module BEGIN { require Module::Cool; # make sure it loads, but don't import yet # get all the functions you want to normally import my @imports = grep { $_ ne 'prefix' } @Module::Cool::EXPORT; # Now do the actual import after filtering; see `perldoc use`. Module::Cool->import(@imports); }; require Exporter; our @ISA = qw/Exporter/; # The 'Exporter' base class does function exporting our @EXPORT = @Module::Cool::EXPORT; # same export list sub prefix { my @args = @_; # stuff before calling the original prefix Module::Cool::prefix(@_); # then do stuff after return ...; # and return as before. } 1; 交换,并使用Cool::Module列表。有关详细信息,请参阅perldoc Exporter

答案 1 :(得分:4)

是。请参阅:perlobj

来自perlobj:

Method Resolution Order

Method resolution order only matters in the case of multiple inheritance. 
In the case of single inheritance, Perl simply looks up the inheritance 
chain to find a method:

    Grandparent
     |
    Parent
     |
    Child

答案 2 :(得分:2)

如果这些方法是一个类的一部分,它将正常工作! : - )

PS C:\dev> perl
package My::Base;

use 5.012;
use warnings;

sub new { return bless {}, shift; }
sub frob { say "in base" }

package My::Child;

use 5.012;
use warnings;

use base 'My::Base';

sub frob { say "in child"; }

package main;

my $base = My::Base->new();
$base->frob();

my $child = My::Child->new();
$child->frob();

给出:

in base
in child
PS C:\dev>

要调用父函数,请使用特殊的SUPER前缀。将上面的示例修改为:

# in My::Child...   
sub frob {
    my $self = shift; 
    $self->SUPER::frob(); 
    say "in child"; 
}

...给出

in base
in base
in child

现在,当调用child的方法时,父和子都会被调用。

答案 3 :(得分:0)

如果Module::CoolOO,这是一个简单示例。

父类

package TestPackage;

use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = {};

    bless $self, $class;
    return $self;
}
sub prefix {
    my $self = shift;

    return "TestPackage";
}

sub is_running {
    my $self = shift;

    return "duh";
}

1;

package TestPackage2;

use warnings; 
use strict;

use base 'TestPackage';

sub prefix {
    my $self = shift;

    return "TestPackage2";
}

1;

使用子类的一些脚本

#!/usr/bin/perl

use strict; 
use warnings;

use TestPackage2;

my $tp2 = TestPackage2->new();

print $tp2->prefix(), "\n";
print $tp2->is_running(), "\n";

输出

$ test.pl
TestPackage2
duh