ハッシュのeach関数を使って「猫はcat犬はdogお茶tea」と表示させるプログラムの主要部分です。
%list = ("猫"=>"cat" , "犬"=>"dog" , "お茶"=>"tea");
while( ($key,$val) = each( %list ) ){
print "$keyは$val";
}
whileの条件部分の意味が分かりません。
・なんで条件部分なのに代入みたいな式が入るのか?
・$keyと$valというのは普通のスカラー変数とは違うのか?
良く分からないので質問の仕方もおぼつかないですが、どなたか分かりやすく説明して頂けないでしょうか?
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 には '犬' が入るわけです。
ですので、このプログラムと最初の質問のプログラムは同じ事をすることになります。
丁寧にお答えくださって有り難うございます。
う~ん、しかし分かったような分からないような・・
一度にたくさんのことを詰め込もうとし過ぎているのか、まだ混乱しています。
これから何度も読み直してみます。
No.1
- 回答日時:
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 の中身を入れ替えるという処理です。
説明が長くなってしまったので、不明点は別途補足ください(^_^;
この回答への補足
補足というか追加質問になってしまうのですが、次のような例文がありました。
foreach $key(keys(%list)){
$val = $list{$key};
print "$keyは$val";
}
この中にある、$list{$key} という部分ですが、これはハッシュの要素へのアクセスを示す $ハッシュ名{'キー名'} でしょうか?
ありがとうございます!条件が真か偽で判断することを忘れていたのと、リスト書式で代入が出来るということを知らなかったのが原因でした。
しかしそうすると each(%list) が返すのは (猫,cat) という書式のものと考えて正解ですか?しかし、 print each(%list); と書くと表示されるのは「猫cat」というようにキーと値がそのまま横に並んだものです。
なんかイマイチ納得できないです・・
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FORTRAN90で書式に変数を使いたい
-
エクセルVBAでTransposeの不思議
-
組み合わせについての質問です...
-
参照配列の要素数の求め方は?
-
UWSCの終了の仕方
-
vb.netからエクセル関数書き込み
-
DoEventsが必要な理由について
-
UWSCのスクリプトで行き詰って...
-
ループフリー
-
RFC822形式の日付を生成するサ...
-
VBAでのコピーのやり方
-
jQuery を使用した経過時間の表...
-
マクロでの繰り返し作業の書き...
-
不安で苦しくて眠れない夜、ど...
-
アルゴリズムやデータ構造を一...
-
アセンブラによるウェイト(WAIT...
-
VBAで3秒だけ時間を止めたい
-
forループで試行を繰返し、その...
-
テキストファイルの行数を指定...
-
VBA横データを縦にしたいです
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
クラスに配列を渡す方法
-
エクセルVBAでTransposeの不思議
-
Excel VBA ユーザーフォームの...
-
VBAのautofilter、criteriaの配...
-
Strawberry Perl for Windows ...
-
二次元配列における要素数のは...
-
VB6で配列の最大値を簡単に求め...
-
リストボックスに縦スクロール...
-
文字の整列(printf)
-
ファイル名に日付・時刻を付与...
-
DataGridViewに配列の値を表示...
-
チェックボックスのperlでの値...
-
一致する要素が格納されている...
-
隣同士の数字を足し合わせる
-
perlで配列の要素が空なのを知...
-
条件に一致した塩基配列を含む...
-
perlで2次元配列をサブルーチ...
-
マクロ Publicでの配列定義
-
二次元配列のインデックスについて
-
perl 配列の要素数について
おすすめ情報