想象一下,我有一个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”方法,我写的新的或原来的来自父模块?
答案 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::Cool
为OO
,这是一个简单示例。
父类
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