0

子クラスのスーパー クラス ジェネリック メソッドへのエイリアスを作成しようとしていますが、うまくいきません。同じクラス内のこのトリックは機能しますが、スーパー/チャイルド トランジションでは機能しないようです。これが本当の基本的な例です。最初の 2 つの呼び出しは機能します。3 番目の呼び出しでは、未定義のサブルーチンに関するエラーが生成されます。SUPER::cat も試してみましたが、うまくいきませんでした。

package foo;

sub cat{
  print("inside foo\n");
}

*bird = \&cat;

package bar;

use base 'foo';

*dog = \&cat;

package main;

foo::cat();
foo::bird();
bar::dog();
4

4 に答える 4

5

オブジェクト指向の継承と単純なシンボルのインポートを混同しています。

あなたが言うようにuse base 'foo'、スーパークラスを宣言します。つまりfoo、 に表示されないメソッドへの呼び出しがチェックされますbar

ただし*dog = \&cat、メソッド呼び出しではありません。これは単にグロブの割り当てであるため、検索は を超えません&bar::cat

真にオブジェクト指向のコードを書いている場合、*bar::doglike への代入は継承メカニズムの要点を無効にします。

Perl のオブジェクト指向機能を確認するには、glob の割り当てをfoo(単にメソッドのエイリアシングを行う場所) に移動し、メソッド呼び出し構文を使用して呼び出しを行います。

このコードでbarは、 には独自のメソッドがなく、からすべてfooを継承していますが、コードは意図したとおりに機能します。

package foo;

sub cat {
  print("inside foo\n");
}

*bird = \&cat;
*dog = \&cat;


package bar;

use base 'foo';



package main;

bar->cat();
bar->bird();
bar->dog();

出力

inside foo
inside foo
inside foo
于 2013-04-17T21:03:42.200 に答える
3

これ:

*dog = \&cat;

次のようにする必要があります。

*dog = \&foo::cat;
于 2013-04-17T20:14:53.933 に答える
1

Borodin が提示したアイデアをさらに一歩進めて、適切な OO を行っているが、親クラスによって提供されるメソッドのエイリアスが必要であり、このサブクラス (およびより深い) でのみ必要であるとします。その場合、これが必要になる場合があります。

#!/usr/bin/env perl

package foo;

sub new { return bless {}, shift }

sub cat{
  print("inside foo\n");
}

*bird = \&cat;

package bar;

use base 'foo';

sub dog { $_[0]->can('cat')->(@_) }

package main;

my $bar = bar->new;
$bar->cat();
$bar->bird();
$bar->dog();

dogこのメカニズムは、スタック トレースに保存されます。そうしたくない場合はgoto &subフォームを使用できますが、理由がわかっている場合にのみ使用する必要があるため、ここでは例を挙げません。

于 2013-04-17T21:15:22.730 に答える