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

そして、何かあるとすれば、私はそれについて何ができますか?

  • さて、私はそれがWin32から継承されていることを理解していますUnixが、ディスパッチは.Win32 -> UnixUnix

  • また、クラス名を渡すだけなので、継承は大きな問題ではないことも理解していFile::Spec::xますが、このように調整するクラスが実際に必要な場合はどうなるのだろうかと考えなければなりません。

4

2 に答える 2

3

概念的には、これは意味がありません。UNIXパスとWindowsパスはありません。

実際には、これも意味がありません。::Unix にない ::Win32 の関数はありません。

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;
}

File::Spec::Win32 であると同時に File::Spec::Unix であると主張するためにオーバーライドisaすることもできますが、それは実際には真実ではなく、クラスがほんの一握りの Win32 のようにしか動作しないため、有用というよりも混乱を招く可能性があります。メソッドの。また、File::Spec にはオブジェクトがないため、実際には出てきません。

オーバーライドcanは必要ありません。正しいコード参照が返されます。

于 2011-04-27T09:21:55.980 に答える