6

タイトルが示すように、perl は、存在しない要素への問い合わせの後に、配列にダミー要素を追加します。照会後に配列サイズが大きくなります。動作の説明:

    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";
           }
         }
       }

実行結果は次のとおりです。

    en@en-desktop ~/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

照会された要素が存在するかどうか、各照会の前に尋ねる以外に、これを回避する方法はありませんか? 私は速度を上げようとしますが、これらの照会によりコードの速度が低下し、読みにくくなります。

有益なヒントを事前にありがとう。

4

1 に答える 1

12

これはあなたが見ている自動活性化です。$ref->[3][0]チェックだけでものメモリにアクセスする場合:

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

次に$ref->[3]、要素番号ゼロをチェックする前に最初に存在する必要があるため、自動有効化によって作成されます。$ref->[3]作成を避けるために、存在するか定義されているかどうかを最初に確認する必要があります。

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

また、常に次を使用する必要があります。

use strict;
use warnings;

次に、警告が表示されます

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

数値等価演算子によって課せられたコンテキストにより、文字列'M'が数値 ( ) に変換されるため、if 節はここで偽陽性を示します。LHS 値はで、これも数値 ( ) に変換されます。これが、式が true と評価される理由です。0==undef0

于 2013-02-10T23:21:34.123 に答える