11

以下は、Perl5.12でのデバッグセッションです。これは意味がありますか?変数UNIVERSALのバージョンをキャッシュし@ISAます。これは、永久にリーファーを使用する場合です。Class::ISA非推奨になる前はClass::ISA::self_and_super_path、内部を呼び出して@ISA配列を再確認するために呼び出していました。今では不要と考えられているので、perlに内部記録を監査させるにはどうすればよいですか?

DB<34> p $papa
Papushka=HASH(0x16bc0300)

DB<35> p $papa->isa('Nanushka')

DB<36> p $papa->isa('Babushka')
1

DB<37> x @Papushka::ISA
0  'Nanushka'
1  'Babushka'

これは(明らかに)テストコードです。同じ結果が得られ、フラットに実行され、テストとして実行され、またはデバッグで実行されます。私はこれの前にあなたに言うべきで@ISA = qw<Babushka>あり、私は実行しました

splice( @ISA, 0, 0, 'Nanushka' );

それが問題ですか?あなたは今までにだけすべきですpush@ISA

4

2 に答える 2

14

の置き換えはClass::ISA::self_and_super_pathですmro::get_linear_isa。これは、mroそれ自体から、または古い perl をサポートしたい場合は、MRO::Compat.

また、@ISAマジック変数です。

$ perl -MDevel::Peek -e'Dump \@ISA'
SV = IV(0x1b92e20) at 0x1b92e28
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x1bbcd58
  SV = PVAV(0x1b93cf8) at 0x1bbcd58
    REFCNT = 2
    FLAGS = (SMG,RMG)
    MAGIC = 0x1bc0f68
      MG_VIRTUAL = &PL_vtbl_isa
      MG_TYPE = PERL_MAGIC_isa(I)
      MG_OBJ = 0x1bbcd40
    ARRAY = 0x0
    FILL = -1
    MAX = -1
    ARYLEN = 0x0
    FLAGS = (REAL)

に注意してくださいPERL_MAGIC_isa。それが、この特定のメカニズムを駆動するものです。

変更されるたびに、その値に依存するすべてのキャッシュの内容が更新されることになっています。

$ perl -E'say Foo->isa(q[Bar]) || 0; @Foo::ISA = qw(Bar Baz); say Foo->isa(q[Bar]) || 0'
0
1

どうやら、キャッシュの無効化が発生しないケースが見つかりました。これはバグだと思います。何らかの理由で、魔法が適切spliceに呼び出されない可能性があります。isa別の方法で変更@ISAを試みることもできます。たとえばunshift、または代入を使用するか、おそらく trymro::method_changed_inを使用すると、さまざまな にバインドされているメソッド解決キャッシュが無効になり@ISAます。

このバグを最小限のテストケースに減らすことができれば、このバグを修正するのに非常に役立ちます。

アップデート:

最小限のテストケースは簡単であることが判明しました。

$ perl -E'say Foo->isa(q[Bar]) || 0; splice @Foo::ISA, 0, 0, q[Bar]; say Foo->isa(q[Bar]) || 0'
0
0

pp_spliceのようなことをしていないことが原因mg_set((SV *)ary)です。pushunshift、および通常の割り当てはそれを正しく行うため、これらのいずれかを使用すると問題が解決するはずです。

別の更新:

perl にコミットしたばかりのこの変更により、問題が修正されます。ただし、splice魔法を呼び出さないという奇妙な動作は 5.8 と 5.10 に既に存在するため、これは回帰ではなく、したがって数か月以内に 5.12.3 の一部にはなりません。来週リリースされる 5.13.6 と、次の北部の春にリリースされる 5.14.0 には、おそらくそれが含まれるでしょう。

于 2010-10-15T16:41:53.873 に答える
4

はい、キャッシュがあります。しかし、@ISAそのキャッシュを無効にせずに変更できるなら、それは perl のバグだと思います。

@ISA = @ISA;行の後に行を追加すると、問題はなくなりますspliceか?

于 2010-10-15T16:38:27.340 に答える