2017-01-27 4 views
1

以下のスクリプトを実行しようとしていて、読み込み専用の変数が変更されていると表示しています。このプログラムでどの変数が変更されているのかわかりませんでした。誰でも下のスクリプトでこのエラーを修正する方法を教えてください。サブルーチンの引数で複数のファイルを処理中にエラーが発生しました

1. use strict; 
2. use warnings; 
3. use diagnostics; 
4. use vars; 
5. use 5.010; 
6. #--------------------------------------------# 
7. 
8. my @array; 
9. if (! open STDERR, ">", "error.txt") { 
10.  die "cannot open the Error file for write";} 
11. &config_parser ('O3CPU.py','config.ini'); 
12. #print "\nNo of elemnts is ". scalar @temp. "\n"; 
13. 
14. sub config_parser { 
15.    foreach (@_) { 
16.     
17.    if (! open HANDLE1, "<", "$_"){ 
18.     die "Cannot open $_: $!"; } 
19. 
20.    my @array; 
21.    while (<HANDLE1>) { 
22.    
23.     chomp $_; 
24.     if ($_=~ (s/Fetch\s?width/Fetch width /i)    || 
25.        (s/Issue\s?width/Issue width /i)    || 
26.       (s/Decode\s?width/Decode width /i)  || 
27.       (s/Rename\s?width/Rename width /i)  || 
28.       (s/wb\s?width/Writeback width /i)  || 
29.       (s/Commit\s?width/Commit width /i)   || 
30.       (s/LQEntries/Load queue size /i)   || 
31.       (s/SQEntries/Store queue size /i)   || 
32.       (s/ROBEntries/ROB buffer size /i)  || 
33.       (s/Int\s?Regs/Integer registers /i)    || 
34.       (s/Float\s?Regs/Floating point registers /i) || 
35.       (s/Pred\s?Type/Branch predictor type /i) || 
36.       (s/Global\s?pred\w+/Global predictor size/i) || 
37.       (s/Local\s?pred\w+/Local predictor size/i) || 
38.       (s/Local\s?Hist\w+/Local History table size/i) 
39.       
40.     ){ 
41.       print "$_\n"; 
42.       push @array, "$_"; 
43.       } 
44. 
45.         } # END of While Loop 
46.       } 
47. #return @array;    # Return the collected results in an array. 
48. close HANDLE1;    # Close the file handle. 
49. }  # END of the Program. 




#---------------------------------------------------------------------------# 

The error message is : 

Modification of a read-only value attempted at stats_parser.pl line 23 (#1) 
(F) You tried, directly or indirectly, to change the value of a 
constant. You didn't, of course, try "2 = 1", because the compiler 
catches that. But an easy way to do the same thing is: 

    sub mod { $_[0] = 1 } 
    mod(2); 

Another way is to assign to a substr() that's off the end of the string. 

Yet another way is to assign to a foreach loop VAR when VAR 
is aliased to a constant in the look LIST: 

     $x = 1; 
     foreach my $n ($x, 2) { 
      $n *= 2; # modifies the $x, but fails on attempt to modify the 2 
     } 

Uncaught exception from user code: 
Modification of a read-only value attempted at stats_parser.pl line 23. 
at stats_parser.pl line 23 
main::config_parser('O3CPU.py', 'config.ini') called at stats_parser.pl line     13 

答えて

2

問題はperlのですが、匿名$_変数のあなたのネストされた用途が好きではありません。

sub config_parser { 
    foreach (@_) { 
     # $_ is in scope here 
     if (!open HANDLE1, "<", "$_") { 
      die "Cannot open $_: $!"; 
     } 
     while (<HANDLE1>) { 
      # This is a different $_ 
      chomp $_; 
     } 
    } 
} 

は、あなたのループ変数名を付け...それはまた、あなたのコードが読みやすくなります。私は古いスタイルのGLOBALの代わりに字句ファイルハンドルを使うこともお勧めします。

sub config_parser { 
    for my $filename (@_) { 
     open my $fh, '<', $filename 
      or die "Cannot open $filename: $!"; 
     while (my $line = <$fh>) { 
      chomp $line; 
      if ($line =~ (...)) { 
       ...; 
      } 
     } 
    } 
} 
} 
+0

ありがとうございます。私は説明したように私のコードをリファクタリングしました。これは、ファイルにアクセスする際に、$行で "初期化されていない$ _エラーが発生しました"という点を除いて正常に動作します。したがって、私はこの問題を解決するために$行の代わりに$ _を使用し、残りのすべては今は正常に動作します。 –

+3

「これは違う$ _」というあなたのコメントは間違っています。問題は 'for'ループの中で' $ _'は定数(文字列 "O3CPU.py")にエイリアスされますが、 '<$fh> 'は' $ _'への自動代入を行います。 qw(bar baz)に対して '$ _ =" foo "を実行することで同じ動作を得ることができます。 – ThisSuitIsBlackNot

+0

Divya:すぐに内部ループに '$ _'を使うだけです。あるいは、 's //'を呼び出すたびに、var名を明示的に参照する必要があります。 'if($ line =〜s/foo \ s +/foo/|| $ line =〜s/bar \ s +/bar/) 'など。 – Joshua

関連する問題