2013-02-10 31 views
6

Khi tiêu đề cho biết, perl thêm các phần tử giả vào các mảng sau khi các yêu cầu không phải là các phần tử hiện có. Kích thước mảng phát triển sau khi điều tra. Minh họa cho hành vi:perl thêm các phần tử giả vào mảng sau khi yêu cầu

my $rarr; 
    $rarr->[0][0] = 'S'; 
    $rarr->[0][1] = 'MD'; 
    $rarr->[1][0] = 'S'; 
    $rarr->[1][1] = 'PRP'; 

    my $crulesref; 
    $crulesref->[0] = $rarr; 

    check_rule('aa', 0); 
    if($rarr->[3][0] == 'M'){ # just check a not existing element 
     print "m\n"; 
    } 

    check_rule('bb', 0); 
    if($rarr->[5][0] == 'M'){ # again: just check a not existing element 
     print "m\n"; 
    } 
    check_rule('cc', 0); 


    sub check_rule($$) 
    { 
     my ($strg,$ix) = @_; 
     my $aref = $crulesref->[$ix]; 
     my $rule_size = @$aref; 
     {print "-----$strg aref:$aref rs:$rule_size aref:'@$aref'\n"; 
      for(my $t1 = 0; $t1 <$rule_size; $t1++){ 
      print "t1:$t1 0:$aref->[$t1][0] 1:$aref->[$t1][1]\n"; 
      } 
     } 
     } 

Kết quả của việc chạy là:

[email protected] ~/dtest/perl/forditas/utf8_v1/forditas/test1 $ perl v15.pl 
    -----aa aref:ARRAY(0x90ed8c8) rs:2 aref:'ARRAY(0x9106cac) ARRAY(0x9106d24)' 
    t1:0 0:S 1:MD 
    t1:1 0:S 1:PRP 
    m      <-------------- finds the non existing 
    -----bb aref:ARRAY(0x90ed8c8) rs:4 aref:'ARRAY(0x9106cac) ARRAY(0x9106d24)   ARRAY(0x9107508)' 
    t1:0 0:S 1:MD 
    t1:1 0:S 1:PRP 
    t1:2 0: 1:    <-- undesired dummy due to inquiry 
    t1:3 0: 1:    <-- undesired dummy due to inquiry 
    m      <-------------- finds the non existing 
    -----cc aref:ARRAY(0x90ed8c8) rs:6 aref:'ARRAY(0x9106cac) ARRAY(0x9106d24) ARRAY(0x9107904) ARRAY(0x9107508) ARRAY(0x910e860)' 
    t1:0 0:S 1:MD 
    t1:1 0:S 1:PRP 
    t1:2 0: 1:    <-- undesired dummy due to inquiry 
    t1:3 0: 1:    <-- undesired dummy due to inquiry 
    t1:4 0: 1:    <-- undesired dummy due to inquiry 
    t1:5 0: 1:    <-- undesired dummy due to inquiry 

Có không có cách nào khác để tránh tình trạng này hơn để hỏi trước mỗi cuộc điều tra, nếu các yếu tố cầu hỏi tồn tại? Tôi cố gắng tăng tốc độ và các yêu cầu này làm chậm mã xuống và làm cho nó dễ đọc hơn.

Cảm ơn trước vì các gợi ý hữu ích.

+0

Tìm kiếm không tồn tại đến từ truy vấn xấu. Thay vì == người ta phải sử dụng eq. Tuy nhiên, đây không phải là vấn đề chính. Các problim chính là việc thêm các yếu tố. – eleonora

Trả lời

12

Đây là autovivification mà bạn đang thấy. Nếu bạn truy cập vào bộ nhớ của $ref->[3][0] thậm chí chỉ với một tấm séc:

if ($ref->[3][0] eq 'M') 

Sau đó, đầu tiên $ref->[3] phải tồn tại trước số lượng phần tử của nó không thể được kiểm tra, vì vậy nó được tạo ra thông qua autovivification. Trước tiên, bạn cần kiểm tra xem có tồn tại hoặc tồn tại $ref->[3] hay không được xác định để tránh tạo.

if (defined($ref->[3]) && $ref->[3][0] eq 'M') 

Ngoài ra, bạn nên luôn luôn sử dụng:

use strict; 
use warnings; 

Sau đó, bạn sẽ thấy những lời cảnh báo

Argument "M" isn't numeric in numeric eq (==) at ... 
Use of uninitialized value in numeric eq (==) at ... 

Các if-khoản cho một dương tính giả ở đây vì chuỗi 'M' được chuyển thành một số (0) vì ngữ cảnh được áp đặt bởi toán tử số bình đẳng ==. Giá trị LHS là undef, cũng được chuyển đổi thành một số (0), đó là lý do tại sao biểu thức đánh giá là đúng.

+6

'if ($ ref -> [3] && $ ref -> [3] [0] eq 'M')' sẽ đủ – ikegami

+3

@ikegami Có, nhưng để minh chứng, có lẽ là một ý tưởng hay riêng. – TLP

+0

Nếu bạn _really_ muốn cụ thể, chắc chắn phải là 'if (ref ($ ref -> [3]) eq 'ARRAY' && $ ref -> [3] [0] eq 'M')'. –

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