2
use parent qw<File::Spec::Unix File::Spec::Win32>;

以及——如果有的话——我能做些什么呢?

  • 好的,我知道Win32继承自Unix,但是调度是Win32 -> Unix并且我希望Unix实现作为默认值,直到我覆盖它并调度到我自己的 Win32 实现。

  • 我也明白,因为File::Spec::x只是传递类名,继承不是一个大问题,但我想知道如果我真的需要一些类来协调这种方式会发生什么。

4

2 回答 2

3

从概念上讲,这没有任何意义。您没有 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);
}
于 2011-04-26T22:45:53.900 回答
1

如果您想要默认为 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不需要覆盖,它将返回正确的代码引用。

于 2011-04-27T09:21:55.980 回答