5

パッケージの呼び出し元を見つける必要があり、コードは次のようになります。

継承.pm:

package Inherited;
our @ISA = qw(BaseClass);
sub new {
   SUPER::new();
}

BaseClass.pm

package BaseClass;
sub new {
  $a = caller(0);
  print $a
}

今、私は別のクラス (MyClass.pm) を持っています:
MyClass.pm:

$obj = Inherited->new();  

これにより、継承が印刷されます。しかし、 MyClassを印刷されたステートメントにする必要があります。

誰かがこれを解決する方法について私を助けてくれませんか??

4

2 に答える 2

5

発信者に引数を与えるときは、何レベル戻るかを指示します。あなたはそれ0に現在のレベルである引数を与えました。1つ上のレベルが必要な場合は、次を追加し1ます。

use v5.12;

package Inherited {
    our @ISA = qw(BaseClass);
    sub new {
       $_[0]->SUPER::new();
    }
}

package BaseClass {
    sub new {
      say "0: ", scalar caller(0);
      say "1: ", scalar caller(1);
    }
}

package MyClass {
    my $obj = Inherited->new;
    }

結果は次のとおりです。

0: Inherited
1: MyClass

質問には常に完全なサンプルプログラムを含めることを忘れないでください。あなたが投稿したPerlコードは、呼び出し元とは関係のない他のさまざまな理由で壊れていました。

于 2012-04-04T17:05:33.253 に答える
1

私があなたの投稿を正しく読んでいれば、コンストラクターを呼び出しているコール スタックの最後のフレームを見つける必要があります。

package BaseClass;
sub new {
    my $a = caller(0);
    for (my $n=0; my @c=caller($n); $n++) {
        last if $c[4] !~ /::new$/;
        $a = $c[0];
    }
    print $a;
}

また

package BaseClass;
sub new {
    my @a;
    unshift @a, [ caller(@a) ] while caller(@a);
    my ($a) = grep { $_->[4] =~ /::new$/ } @a;
    print $a // caller(0);
}

2 番目のコード スニペットは、コンストラクターではない中間関数呼び出しがある場合 (たとえば、呼び出しスタックが次のように見える場合) を処理します。

 GrandChild::new
 GrandChild::init
 Inherited::new
 BaseClass::new

最初のスニペットは の呼び出し元を返しInherited::newます (これはおそらくGrandChildであり、2 番目のスニペットは の呼び出し元を返しGrandChild::newます。

于 2012-04-04T15:15:06.260 に答える