2010-10-15 8 views
11

Aşağıdaki, Perl 5.12'de bir hata ayıklama oturumu. Bu bir anlam ifade ediyor mu? UNIVERSAL,değişkeninin bir sürümünü önbelleğe alır; Class::ISA'dan önce geri çevrilmeden, dahili kullanıcılara @ISA dizisinde yeniden bağlantı kurmak için Class::ISA::self_and_super_path'u aradım. Artık gereksiz olarak değerlendirildiğinden, dahili kayıtlarını denetlemek için nasıl perl aldınız?Perlit 5.12.2'de @ISA üzerinde ekleme kullanılarak bir problem var mı?

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' 

Bu, test kodudur (açıkçası). Aynı sonuçları almak, düz koşmak, bir test olarak çalıştırmak veya hata ayıklamakta. Bu @ISA = qw<Babushka> için o önce söylemelidir ve ben

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

sorun olur gerçekleştirilen?'a sadece push mu?

cevap

14

Class::ISA::self_and_super_path için yedek mro::get_linear_isa olduğunu. Bu, mro'un kendisinden ya da MRO::Compat aracılığıyla eski perileri desteklemek istiyorsanız kullanılabilir.

Ayrıca @ISA sihirli bir değişkendir.

$ 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) 

Not PERL_MAGIC_isa. Bu belirli mekanizmayı harekete geçiren şey budur.

o değiştiğinde

, değeri güvenmek herhangi önbelleklere içeriği güncellenmesi gerekiyor.

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

Görünüşe göre, önbellek geçersiz kılma gerçekleşmediği bir durum buldunuz. Bunu bir hata olarak görüyorum. Şanslar splice, nedense isa büyüsünü uygun şekilde çağırmıyor. Sen unshift kullanarak örneğin ya bir görev için, alternatif bir yolla @ISA değiştirmeye çalışın, ya da muhtemelen çeşitli @ISA s bağlanmıştır yöntem çözünürlüğü önbelleklerini, geçersiz olur mro::method_changed_in, deneyebilirsiniz. Eğer minimal testcase için bu hatayı azaltmak olsaydı

, bu sabit bu hata almakla derece yararlı olurdu.

Güncelleme:

bir asgari testcase kolay olduğu ortaya çıktı:

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

Bu mg_set((SV *)ary) gibi bir şey yapmıyor pp_splice kaynaklanır. push, unshift ve düzenli ödevler bunu doğru yapar, bu yüzden bunlardan birini kullanarak sorunu düzeltmeniz gerekir.

Başka Güncelleme:

This change, sadece Perl programının kararlı, sorunu giderir. Ancak, splice'un sihri çağırmamanın tuhaf davranışı, 5.8 ve 5.10'da zaten mevcut olduğundan, bu bir gerileme değildir ve bu nedenle birkaç ay içinde 5.12.3'ün bir parçası olmayacaktır. Önümüzdeki hafta piyasaya sürülecek 5.13.6 ve önümüzdeki ilkbaharda 5.14.0 muhtemelen buna sahip olacak.

+0

Kazanmak için bir yama! Teşekkürler. – Axeman

+1

@Ether: http://rt.perl.org/rt3/Public/Bug/Display.html?id=78400 – Axeman

+0

Yama rafı için teşekkürler! – Ether

4

Evet, bir önbellek var. Ancak, bu önbelleği geçersiz kılmadan @ISA'u değiştirebilirseniz, perl'de bir hata olduğunu düşünürdüm. Eğer splice satırdan sonra satır @ISA = @ISA; eklerseniz

senin sorunun kayboluyor mu?

+0

Kesinlikle @ ISA = @ ISA'yı deneyecek. Bunun haricinde, daha çok @ $ isa_ref = @ $ isa_ref' olacaktır. Nerede $ isa_ref = * Papushka :: ISA {ARRAY} '. – Axeman

İlgili konular