こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

perlのプログラミングで悩んでいます

open(IN,"<data/list.cgi");
@list = <IN>;
close(IN);

このようなプログラムで、


'abc','def','ghi'

とだけ書かれた「list.cgi」をdataディレクトリに用意しています。


そして、print "$list[0]";で読み込むと、

'abc','def','ghi'

と全て表示されてしまいます。


原因がわからないので、質問しました。
お願いします。

投稿日時 - 2011-01-15 13:56:05

QNo.6449317

困ってます

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

原因ははっきししています。

<>をリストのコンテキストで使用すると、ファイル全体を読み込み、行毎に分解したリストを返します。
# Perlを使う上でリストとスカラーのコンテキストは重要なものです。しっかり理解してください。

このプログラムでは @listにlist.cgiの各行を要素とするリストが入ります。
$list[0]には list.cgiの1行目になっています。
ファイルの1行目には 'abc','def','ghi' ですから、 'abc','def','ghi' になります。
ファイルには2行目以降がないので、$list[0]で全部であり、$linst[1]以降には何も入っていません。

以上のように、まったく仕様通りの動作です。なんの不思議もありません。
原因は、「違う動作を期待する、あなたの不理解」です。


カンマで分解したいのでは、と推測されますが、それなら、次のような方法を使います。
・split関数を使う
・入力セパレータを表わす特殊変数 $/ を $/=',' と変更して、<>が「カンマ毎に分解する」ようにする(他にも影響が大きいのであまり勧められない)


list.cgiというファイル名からすると、 ファイルの内容をPerlでの記述と解釈させようとしているのではないか、とも推測されます。
@list=('abc','def','ghi');
と書いたのと同じ状態にしたかったのでしょうか。

<>にそんな機能はありません。
他のファイルに書かれたPerlスクリプトを利用するには、次の方法があります。
・require を使う
・モジュールにしてuseを使う
・<>で文字列として取り込んで evalで解釈する

単にリストの内容を別ファイルに記述しただけなら、その別ファイルをPerlスクリプトとして書く必要はありません。
・<>で取り込んで必要に応じて文字列操作する

投稿日時 - 2011-01-15 14:35:16

split はいかがですか?
その場合は、' ' でくくる必要はないのかもしれません。

open(IN,"<data/list.cgi");
@list = split( /,/, <IN>);
close(IN);
print "$list[0]";

'abc'

となると思います。

投稿日時 - 2011-01-15 14:17:46

あなたにオススメの質問