use parent qw<File::Spec::Unix File::Spec::Win32>;
以及——如果有的话——我能做些什么呢?
好的,我知道
Win32
继承自Unix
,但是调度是Win32 -> Unix
并且我希望Unix
实现作为默认值,直到我覆盖它并调度到我自己的 Win32 实现。我也明白,因为
File::Spec::x
只是传递类名,继承不是一个大问题,但我想知道如果我真的需要一些类来协调这种方式会发生什么。
use parent qw<File::Spec::Unix File::Spec::Win32>;
以及——如果有的话——我能做些什么呢?
好的,我知道Win32
继承自Unix
,但是调度是Win32 -> Unix
并且我希望Unix
实现作为默认值,直到我覆盖它并调度到我自己的 Win32 实现。
我也明白,因为File::Spec::x
只是传递类名,继承不是一个大问题,但我想知道如果我真的需要一些类来协调这种方式会发生什么。
从概念上讲,这没有任何意义。您没有 unix 路径和 Windows 路径。
实际上,这也没有任何意义。::Win32 中没有 ::Unix 中没有的函数。
File::Spec 已经滥用了继承,而你正在更进一步。这里不需要继承!
无论如何,这将等同于您所拥有的,减去错误:
use parent qw( File::Spec::Unix );
use File::Spec::Win32 qw( );
sub isa {
my ($self, $class) = @_;
return $class eq 'File::Spec::Win32' || $self->SUPER::isa($class);
}
如果您想要默认为 File::Spec::Unix 通常并专门使用 File::Spec::Win32,那么您不想使用多重继承。File::Spec::Unix 已经从 File::Spec::Win32 继承,所以你设置了一个(大部分)C3 不想解决的菱形继承。
Unix
/ \
Win32 |
| |
YourCode
您只想从 File::Spec::Unix 继承,然后根据需要使用 File::Spec::Win32。
package My::FileSpec;
use parent qw(File::Spec::Unix);
require File::Spec::Win32;
sub devnull {
my $class = shift;
return $class->File::Spec::Win32(@_);
}
如果你想变得聪明,你可以去掉包装方法。
*devnull = File::Spec::Win32->can("devnull");
最后,您可以将其放入循环中以避免重复。
my @Win32_Methods = qw(devnull tmpdir);
for my $method (@Win32_Methods) {
my $code = File::Spec::Win32->can($method);
die "File::Spec::Win32->$method does not exist" unless $code;
no strict 'refs';
*{$method} = $code;
}
您可以覆盖isa
以声明您是 File::Spec::Win32 以及 File::Spec::Unix 但这并不是真的,并且可能会比有用更令人困惑,因为您的类只像 Win32 一样为少数的方法。此外, File::Spec 没有对象,因此它实际上不会出现。
can
不需要覆盖,它将返回正确的代码引用。