2010-10-15 18 views
11

Sau đây là phiên gỡ lỗi trên Perl 5.12. Liệu điều này có ý nghĩa gì? Có UNIVERSAL bộ nhớ cache phiên bản của biến số @ISA, nếu sử dụng vĩnh viễn thereafer. Quay lại trước khi Class::ISA không còn được dùng nữa, tôi đã từng gọi Class::ISA::self_and_super_path để yêu cầu nội bộ cập nhật tại mảng @ISA. Vì nó bây giờ được coi là không cần thiết, làm thế nào để bạn có được perl để kiểm toán hồ sơ nội bộ của nó?Có vấn đề gì trong perl 5.12.2 sử dụng mối nối trên @ISA không?

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' 

Đây là mã kiểm tra (hiển nhiên). Nó nhận được kết quả tương tự, chạy bằng phẳng, chạy dưới dạng thử nghiệm hoặc chạy trong gỡ lỗi. Tôi nên cho bạn biết rằng trước khi điều này @ISA = qw<Babushka> và tôi đã thực hiện

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

Đó có phải là sự cố không? Nếu bạn chỉ bao giờ push lên @ISA?

Trả lời

14

Thay thế cho Class::ISA::self_and_super_pathmro::get_linear_isa. Điều đó có sẵn hoặc từ mro chính nó, hoặc, nếu bạn muốn hỗ trợ perls cũ, thông qua MRO::Compat.

Ngoài ra, @ISA là một biến ảo thuật.

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

Lưu ý PERL_MAGIC_isa. Đó là điều thúc đẩy cơ chế đặc biệt này.

Bất cứ khi nào thay đổi, nội dung của bất kỳ bộ nhớ cache nào dựa trên giá trị của nó được cho là sẽ được cập nhật.

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

Dường như bạn đã tìm thấy trường hợp không có hiệu lực bộ nhớ cache. Tôi coi đây là lỗi. Rất có thể là splice, vì một số lý do, không gọi phép thuật isa một cách thích hợp. Bạn có thể thử sửa đổi @ISA theo cách khác, ví dụ sử dụng unshift hoặc bài tập hoặc có thể thử mro::method_changed_in, điều này sẽ làm mất hiệu lực bộ đệm giải pháp phương pháp, được liên kết với các số @ISA s khác nhau.

Nếu bạn có thể giảm lỗi này xuống một testcase tối thiểu, điều đó sẽ cực kỳ hữu ích trong việc sửa lỗi này.

Cập nhật:

Một testcase tối thiểu hóa ra là dễ dàng:

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

này là do pp_splice không làm một cái gì đó giống như mg_set((SV *)ary). push, unshift và các bài tập thường xuyên thực hiện điều đó một cách chính xác, do đó, việc sử dụng một trong các cách này sẽ khắc phục sự cố của bạn.

Một Cập nhật:

This change, mà tôi chỉ cam kết perl, sửa chữa vấn đề này. Tuy nhiên, vì hành vi kỳ lạ của splice không gọi ma thuật đã có trong 5.8 và 5.10, nó không phải là hồi quy và do đó sẽ không là một phần của 5.12.3 trong một vài tháng. 5.13.6, sẽ được phát hành vào tuần tới, và 5.14.0, mùa xuân phía bắc tiếp theo, có lẽ sẽ có nó.

+0

Một bản vá cho chiến thắng! Cảm ơn. – Axeman

+1

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

+0

Cảm ơn bạn đã phát hành bản vá !! – Ether

4

Có, có bộ nhớ cache. Nhưng nếu bạn có thể sửa đổi @ISA mà không làm mất hiệu lực bộ nhớ cache đó, tôi sẽ coi nó là một lỗi trong perl.

Sự cố của bạn có biến mất nếu bạn thêm dòng @ISA = @ISA; sau dòng splice của mình không?

+0

Chắc chắn sẽ thử '@ ISA = @ ISA'. Ngoại trừ nó sẽ giống như '@ $ isa_ref = @ $ isa_ref'. Nơi '$ isa_ref = * Papushka :: ISA {ARRAY}'. – Axeman

Các vấn đề liên quan