OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

紙谷氏の「Perl/CGI入門」、ハッシュeach関数の例題について

  • 困ってます
  • 質問No.131258
  • 閲覧数97
  • ありがとう数4
  • 気になる数0
  • 回答数2
  • コメント数0

お礼率 58% (7/12)

ハッシュのeach関数を使って「猫はcat犬はdogお茶tea」と表示させるプログラムの主要部分です。

%list = ("猫"=>"cat" , "犬"=>"dog" , "お茶"=>"tea");
while( ($key,$val) = each( %list ) ){
  print "$keyは$val";
}

whileの条件部分の意味が分かりません。
・なんで条件部分なのに代入みたいな式が入るのか?
・$keyと$valというのは普通のスカラー変数とは違うのか?
良く分からないので質問の仕方もおぼつかないですが、どなたか分かりやすく説明して頂けないでしょうか?
通報する
  • 回答数2
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.2

 はいはい、補足です(笑)

>each(%list) が返すのは (猫,cat) という
 その通りです。
 「猫」と「cat」がそれぞれ配列変数の値として入ります。

>print each(%list); と書く
 print 文における配列の扱いは例外で、「中身をセパレータなしで並べて表示する」という動きをします。(セパレータを入れたい場合はシステム変数に設定)
 ですのでこの場合、print 文は、each(%list) が返した('猫','cat')という配列の中身を、セパレータなしでつなげて「猫cat」と表示したわけです。

>この中にある、$list{$key} という部分ですが
 はい、その通りです。
 まず関数 keys は、ハッシュ配列変数のキー名すべてを配列にして返す関数です。
 foreach は、その「返された配列」を1つ1つ $key に入れてループしてくれます。
 すると、最初のループでは $key には '猫' が入ることになるわけですから、$list{$key} は $list{'猫'} と同じ意味になります。
 もちろん、次のループでは $key には '犬' が入るわけです。
 ですので、このプログラムと最初の質問のプログラムは同じ事をすることになります。
お礼コメント
mika-o

お礼率 58% (7/12)

丁寧にお答えくださって有り難うございます。
う~ん、しかし分かったような分からないような・・
一度にたくさんのことを詰め込もうとし過ぎているのか、まだ混乱しています。
これから何度も読み直してみます。
投稿日時 - 2001-09-07 14:49:04
-PR-
-PR-

その他の回答 (全1件)

  • 回答No.1

 C言語もそうなんですが、Perl の条件式の特徴は、「比較と代入を同時に行える」という点です。そのために、比較演算子(==)と代入演算子(=)が別になってるんです。  このとき、比較式を記述しなければならない場所(今回の場合は while の中)に代入式だけを記述すると、Perl は自動的に、「代入された値が真か偽か」によって判定を行います。  真とは、0以外の数値や、undefine、また ...続きを読む
 C言語もそうなんですが、Perl の条件式の特徴は、「比較と代入を同時に行える」という点です。そのために、比較演算子(==)と代入演算子(=)が別になってるんです。

 このとき、比較式を記述しなければならない場所(今回の場合は while の中)に代入式だけを記述すると、Perl は自動的に、「代入された値が真か偽か」によって判定を行います。

 真とは、0以外の数値や、undefine、または null ではない文字など、何かを処理するのに適した値です。
 逆に偽とは、0、undefine、null です。

 each は、ファイルの読み込みと同じようにハッシュ変数の中身を、呼び出すごとに順番に「配列として」返す変数で、すべての配列を呼び出し終わると null を返します。
 ですので、正常なデータが返されているうちは、while はそれを「真」であると解釈し処理を繰り返しますが、each が null を返すと、すべての処理が終わったのだと解釈し、ループを抜けるわけです。

 それから、($key, $val) という記述ですが、こんな記述ができるのは、俺が知る中では Perl だけです。(マイナーな言語には他にもこれができるものがあるようですが)
 Perl の関数が「配列」という巨大なデータを返すとき、それを受け取るための手法の1つがこの書き方です。
 通常は配列を返す関数に関しては、受け取り側も配列を記述するのが普通です。

  @kv = each( %list );

 この書き方をすれば、$kv[0]、$kv[1] にそれぞれ値が入りますが、これでは少し面倒です。
 そこで、Perl では、($key, $value) という括弧そのものを、「1つの仮的な配列」として扱うことができるのです。
 ですのでこの処理が終わってしまえば、$key も $value もそれぞれスカラー変数として扱えます。

 これを利用すれば、

  ($a, $b) = ($b, $a);

 という記述も出来ます。これは、$a と $b の中身を入れ替えるという処理です。

 説明が長くなってしまったので、不明点は別途補足ください(^_^;
補足コメント
mika-o

お礼率 58% (7/12)

補足というか追加質問になってしまうのですが、次のような例文がありました。

foreach $key(keys(%list)){
  $val = $list{$key};
  print "$keyは$val";
}

この中にある、$list{$key} という部分ですが、これはハッシュの要素へのアクセスを示す $ハッシュ名{'キー名'} でしょうか?
投稿日時 - 2001-09-07 13:33:41
お礼コメント
mika-o

お礼率 58% (7/12)

ありがとうございます!条件が真か偽で判断することを忘れていたのと、リスト書式で代入が出来るということを知らなかったのが原因でした。
しかしそうすると each(%list) が返すのは (猫,cat) という書式のものと考えて正解ですか?しかし、 print each(%list); と書くと表示されるのは「猫cat」というようにキーと値がそのまま横に並んだものです。
なんかイマイチ納得できないです・・
投稿日時 - 2001-09-07 13:04:21


このQ&Aのテーマ
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ