Perlで配列の値が関数に引き継がれない原因と解決方法

このQ&Aのポイント
  • Perlでレンタルサーバ上でプログラムを作成している際、配列の値が関数に引き継がれない問題が発生しました。この問題の原因として、別のサーバへの移行時に配列の引数が正しく引き継がれていない可能性が考えられます。また、呼び出し先で行われているwhile文の追加によって問題が解決されましたが、その理由は配列の値が参照可能になったためです。
  • 問題の原因として考えられる点は、移行時に関数の引数の受け渡し方法や配列の扱いに関する違いがあることです。また、while文の追加によって問題が解決されたのは、each関数が配列の内部ポインタを操作するため、while文の前で配列のポインタが終端に位置していた可能性があるためです。そのため、while文を一つ追加することでポインタが先頭に戻り、配列の値が参照可能になったと考えられます。
  • この問題を解決するためには、移行先サーバと元のサーバの環境や設定の違いを確認し、特に関数の引数の受け渡し方法や配列の扱いについて注意する必要があります。また、each関数や配列のポインタ操作についても理解しておくと良いでしょう。さらに、問題が発生した場合には、配列の内容を表示するなどデバッグを行い、原因を特定して対応することが重要です。
回答を見る
  • ベストアンサー

Perlで配列に設定した値が関数に引き継がれない。

レンタルサーバ上でPerlのプログラムを作成しているの ですが、動作でよくわからないことがあるので、教えてください。 Perlのプログラムがあるサーバで動作していて、それを 他のサーバに移したのですが、正しく動作しなくなりました。 調べてみると、関数を呼んでいるところで配列の値がうまく 引き継がれていませんでした。 呼び出しの処理は次の通りです。 ●呼び出し元 ret= &SubModule(*DATA1); ●呼び出し先 sub SubModule { local(*DATA1) = @_ if @_; while(($key, $value) = each(%DATA1)) { #配列に対する処理 } #以下省略 このような処理の時に呼び出し元では配列DATA1に 値が入っているのに呼び出し先のSubModuleでは 空になりwhile文を素通りして「#配列に対する処理」 を実行しません。 いろいろ試しているうちに、呼び出し先に1つ余計な whileを入れると配列DATA1に値が入ってきました。 つまり次のように変更すると、うまくいきました。 呼び出し先 sub SubModule { local(*DATA1) = @_ if @_; while(($key, $value) = each(%DATA1)) { } while(($key, $value) = each(%DATA1)) { #配列に対する処理 } #以下省略 こうすると 「#配列に対する処理」が実行されました。 教えていただきたいのは以下の2点です。 (1)元のサーバでは問題なく動作していたのですが、  別のサーバでは、配列の引数がうまく引き継がれ  なくなりました。どういう原因が考えられるでしょうか。  処理上何かまずいところがあるのでしょうか。 (2)呼び出し先でwhile文を一つ入れることで、配列の  値が参照できるようになったのですが、これは  なぜでしょうか。 よろしくお願いします。

  • Perl
  • 回答数2
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.1

> (1)元のサーバでは問題なく動作していたのですが、..... 私自身使ったことがないのでよくわからないのですが、mod_perl 等の常駐型の Perl を使うとグローバル変数などに不都合が出るというのは聞いたことがあります。サーバを変更して正しく動作しなくなったのなら、その可能性もあると思います。 > (2)呼び出し先でwhile文を一つ入れることで、配列の ..... ハッシュは iterator (反復子) と呼ばれる内部的な変数で、どこまで読んだか記憶しています。while ループで空リストを返すまで実行すれば iterator はリセットされますが、そうでない場合は次の位置から再開されることになります。次のコードを参照してみてください。 %hash = (one => 1, two => 2, three => 3); @key_list = keys %hash; print "1回目:\n"; while (($key, $value) = each %hash) { print "$key => $value\n"; last if $key eq $key_list[-1]; } print "2回目:\n"; while (($key, $value) = each %hash) { print "$key => $value\n"; } print "3回目:\n"; while (($key, $value) = each %hash) { print "$key => $value\n"; } 上のコードは1回目は出力されますが、iterator はリセットされていません。2回目は何も出力しませんが、質問の余計な while と同様に iterator をリセットします。そのため、3回目は出力されることになります。keys や values はその都度 iterator をリセットするので、次のようにするのも一方法かと思います。 foreach $key (keys %DATA1) { $value = $DATA1{$key}; ...

tomtomoo
質問者

お礼

配列ではなくてハッシュって言うんですね。よくわからずに 使っていました。ご指摘のようにリセットされていないので whileでループしないのかもしれません。 大変参考になりました。ありがとうございました。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

今どきの Perl ならリファレンスを使うところだなぁ. ちょ~古代の Perl だったらしょうがないけど.

関連するQ&A

  • リスト内の値を分割して、2つの配列に入れるには

    初歩的な質問になるかと思いますが、 どうかご指導願います。 リストにはHashMap用のkeyとvalueが lists.add("key1"); lists.add("value1"); lists.add("key2"); lists.add("value2"); lists.add("key3"); lists.add("value3"); ↑のような感じでセットされています。 このリストの要素をキーと値を別々の配列にセットしたいのですが、 どうすればいいのかわかりません。 配列 key         配列 value String key[]          String value[] key[0] = "key1";       value[0] = "value1";  key[1] = "key2";       value[1] = "value2";   key[2] = "key3";       value[1] = "value3"; ↑のような感じにfor文やwhileを使ってできると思うのですが、 ど素人のため全くうまくいきません。 。ご指摘ご指南頂きたく思います。

    • ベストアンサー
    • Java
  • 連想配列からの値の取り出し

    お世話様です。 タイトルにもありますが連想配列を作成した後(以下に記述例)に その配列からキーを指定して値を取得したいと思っております。 array_keys関数だと値を指定してキーを取得するみたいで うまくいきませんでした。 何かよい方法ありませんでしょうか? //配列に格納 while (条件) {   $aParaOra += array((キー) => (値)); }

    • ベストアンサー
    • PHP
  • perlのeach関数の動き?

    perl5.8ですがeach関数を使って何回か動かすと、ハッシュ内にあるはずのデータが取得できなくなります。 my %hash = ('a'=>100, 'b'=>50); for(1..100){ while( my ($k, $v) = each %hash ){ if($k eq 'a'){ ... 通過しなくなる。 } } } PHPでは、配列に対してですが、reset関数というものがありますが perlでは、何か対策でもあるのでしょうか? 現在は、keys関数で代用しています。 eachでループは無理なのでしょうか?

    • ベストアンサー
    • Perl
  • 連想配列でこういう処理をする関数を探しています

    PHP5.2.4を使用しています。 どういうふうに説明してよいのか分かりませんが、 $arr = array(  'key1' => array('value1'=>1,'value2'=>11),  'key2' => array('value1'=>2,'value2'=>22),  'key3' => array('value1'=>3,'value2'=>33), ); という連想配列を例えばキー'value2'の値だけが欲しく、 $arr = array(  'key1' => 11,  'key2' => 22,  'key3' => 33, ); と、変換したいのですが、そのような関数はあるのでしょうか? またこのような処理をする関数を自作する場合、 どのような関数名が適切でしょうか?(array_○○○)

    • ベストアンサー
    • PHP
  • perlでの配列について

    配列の配列について教えてください。 以下のようなテキストから値を取得し、A,B,Cの値をそれぞれ別の配列に格納し、A,B,Cの平均値を出す処理を行っているとします。 ----- A=100 B=200 C=300 A=110 B=210 : ----- 現状、以下のような状態です。 @arrayA=(); @arrayB=(); @arrayC=(); : (テキストを読み込み) : ・読み込んだ行がA=XXXならarrayAにpush push(@arrayA,"100"); ・読み込んだっ行がB=XXXならarrayBにpush push(@arrayB,"100"); : (各配列の要素の平均値を出す) このやり方だと、グループが増えるとそのまま行数が増えて冗長なので、グループごとの配列を1つの配列にまとめたいのです。 Webで初期値を入れた形で説明しているのはよくみるのですが、今回のように空の配列に値をいれていくにはどうすればよいのでしょうか?(そもそも宣言の仕方もわかりません)。 また、配列の配列?とした場合、以下のような処理はできるのでしょうか? (1)配列の1つ目の要素(の配列)にpushする(現状でのarrayAにpushに該当) push(@arrayAll[0],"test");

  • perl:2次元配列の値の取り出し方

    お世話になります。Perlの2次元ハッシュ配列の値の取り出し方をお教えください。以下の コード中、%test だと、値を入れるのが煩雑になるので、%test2や%test3のようなコードにしようと思うのですが、入れた値をとりだすコードが分かりません。。。ご指導ください。 my %test; $test{'A'}{'a'} = 1; $test{'A'}{'b'} = 2; my %test2 = ( 'P' => ['a'=>1, 'b'=>2], 'Q' => ['a'=>3, 'b'=>4] ); my %test3 = ( 'P' => ('a'=>1, 'b'=>2), 'Q' => ('a'=>3, 'b'=>4) );

    • ベストアンサー
    • Perl
  • 配列に値を入れたいのですが・・

    Perlは超初心者です。 既存テキストデータファイルを編集して、上書き保存できるようしたくて、次のようなテキストデータを ===== 山田 田中 加藤  ・  ・ ===== 読込んで、次のようなHTMLを作成する様にしました。 <input type='text' name='name[0]' value='山田'> <input type='text' name='name[1]' value='田中'> <input type='text' name='name[2]' value='加藤'>             ・             ・ ここから、テキストボックスの値を編集して、Submitで別Perlプログラムにデータを送信し、次のようなプログラムでデータを読込めば ======================================================================== $count = $in{'count'}; #データのレコード件数です。ここは問題ありません。 for($x=0;$x<=$count;$x++){ $simei[x]=$in{'name[x]'}; } ======================================================================== $simei[0]=山田、$simei[1]=田中、$simei[2]=加藤、・・・と配列変数に入って、それをファイルに上書きするつもりだったのですが、変数には何も代入されないようです。 どうすれば、私の思うようになるでしょうか?

    • ベストアンサー
    • Perl
  • 静的ハッシュの配列のキーに対応する値の数の多さ順で表示させたい

    ハッシュのキーに対応する値の数の多さ順で表示させたいと考え、下記の所まで試行錯誤しておりますが、どうにも思ったようにソートできずにおります。 #!/usr/bin/perl use strict; my(%a, $i, $j ,$allarray ,@keys ,@keys2 ,%hash ,%files ,$a_mumei_ref ,$key ,$value ,@value ,$x ,$files); # ハッシュの配列を静的に作る %a = ( '0' => [ qw(0) ], '1' => [ qw(1 1) ], '3' => [ qw(3 3 3) ], '7' => [ qw(7 7 7) ], '2' => [ qw(2) ], '4' => [ qw() ], '5' => [ qw() ], '6' => [ qw() ], '8' => [ qw(8 8) ], '9' => [ qw(9) ], ); @keys = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %a; #ハッシュのキーを数字順で表示 foreach (@keys){ print $_ ."\n"; } # 静的に作ったハッシュの配列を取り出してみる foreach $i (sort keys %a) { for ($j = 0; $j <= scalar(@{$a{$i}})-1; $j++) { print '$a{'. $i. '}['. $j. ']='. $a{$i}[$j]. ' '; } $allarray=scalar(@{$a{$i}})-1; print "No$i:kosuu:$allarray"; print "\n"; #配列の値の個数を調べその配列を作成 my($a_mumei) = $allarray; $a_mumei_ref = \$a_mumei; $files{"$i"}=($i,$a_mumei_ref); } #each関数で%filesの中身を表示 while ( ( $key , $value ) = each %files ){ print "key:$key value:$$value\n" ; } #試行錯誤 foreach $x (sort { $files{$b} <=> $files{$a} } keys %files){ print "$x => $files->{$x}\n"; } @keys2 = sort {$hash{$a} <=> $hash{$b}} keys %files; #@keys2 = sort { $hash{$b} <=> $hash{$a} || length($b) <=> length($a) || $a cmp $b } keys %files; #@keys2 = sort { $hash{$a} cmp $hash{$b} } keys %files; print "@keys2\n"; print "\n"; __END__; 私のイメージしておりますのは、ソートした結果がハッシュのキーに対応する値の数の多さ順で下記のように表示させたいのですが、 どのようにすれば可能でございますか、ご教授願えませんでしょうか key:3 value:2・・・この場合valueは配列の個数 key:7 value:2 key:8 value:1 key:1 value:1 key:9 value:0 key:2 value:0 key:0 value:0 key:6 value:-1 key:4 value:-1 key:5 value:-1

    • ベストアンサー
    • Perl
  • phpでのセレクトボックスの値を配列で指定

    セレクトボックスの値をループで繰り返してvalueを設定しているのですがvalueの数が多くなればかなり見づらく 修正もしにくいのでvalue値を配列などで指定したいと思っています。 その場合、どのようにしてvalue値に配列を設定すればよろしいのでしょうか。 また配列でvalueを設定した場合[selected]などで初期値を設定する方法も分からなかったので 何かわかりやすくかつ少ない行数で胥吏できる方法があればご教授お願いします。 <?php for ($data = 1; $data < 5; $data++) { ?> <tr><td> <select name="test<?php echo $data?>"> <option value=1>1 <option value=2>2 <option value=3>3 <option value=4>4 <option value=5>5 <option value=6>6 <option value=7>7 <option value=8>8 <option value=9>9 <option value=10>10 </select> <?php } ?> ※option valueが20とか30とかになるとかなり見づらい処理かなと思います。 配列を変えるだけでいいようにしたいです。

    • 締切済み
    • PHP
  • 関数から配列を返すには?

    return で配列を返すにはどうしたらよいのでしょうか。 例えば以下のような場合です。 int main (){ char Value[] = "999"; int a;  a = test(Value);  printf ("%d", a);   } int test(char *Value) { int nVal[255]; ここで nVal に適当な処理をして・・・  return Value; }  int a を配列とかにしてみましたけど、コンパイラが 通りません。 要は配列数値を main で受け取って表示したいのですが、 本日C言語はじめたところなので、教えていただければありががたいです。