- ベストアンサー
Perlについての質問
- Perlについての質問について解説します。
- 質問内容に関するPerlのコードの問題点と正しい書き方について説明します。
- 質問者が実現したい結果について解説します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
間違っている点 1.受信データをベタのまま使用している たぶん学校の課題かなにかでしょうが、この状況では練習問題にもなりません。 POSTやGETのメソッドで受信したデータは名前と値にそれぞれ分離して扱いましょう。 現状ではボタンもフォームの一部なのでボタンデータの値(例:BT1=送信など)も受信文字列に入っているはずです。 それをそのまま正規表現でパターンマッチをとっても無意味でしょう。 さらに、エンコードされている可能性も考慮してデコード処理も必要でしょう。 連想配列に代入して処理するのが一般的です。 2.ファイルを開く 書きこみの必要性がないなら出来るだけ「読み込み」だけで処理することです。 データ量にもよりますが「ファイルを開いている状況は出来るだけ短時間に押さえる」ように処理するのが吉です。 この場合データ量が少ないので、一気呵成に配列へ読み込んでファイルはさっさと閉じましょう。 配列のループで処理すればいいのです 3.ファイルを削除 オリジナルデータは出来るだけ残すようにする。 HDDの空き容量が問題にもなりますが、ここはunlinkよりもrenameを使って以前のデータを残すべきでしょう。 いまどきのマシンでテキストデータが圧迫するようなマシンならサーバなんぞには向いていません。 4.書き込み処理 状況にもよりますが、前の回答者様が述べているようにファイルのブロック処理があったほうがいいでしょう。 ただし、シェバングをみるとWindows上で組んでいるようなのでPerlのファイルロックはあてにできません。 CGIでは古典的手法なのですが、外部ファイルのステータスを利用するなど、裏技を利用するのが良いでしょう。 「perl」「ファイルロック」などでググれば見つかるでしょう。 また出力データは丁寧に出しましょう。配列をベタでガバーではまともに処理ができていてもいなくても消された元ファイルは成仏できません。 せっかく出力イメージを提示しているのですからそのように出力するよう少しは努力してください。 5.メインの処理の部分 正直、結果の部分とプログラムの内容があまりに乖離しすぎていて、どんな処理をしたいのかが汲み取れないので以下の点を明確にしてください ・受信データとファイルデータを比較しているが左辺が同一のデータ部分だけを上書きするような仕組みなのでしょうか? ・フォームに入力値がなかった場合の処理は必要ないのか?→必要ないなら比較などせずにマルマル上書きすれば済む話ですよね。 追伸: まえの質問でも同じなんですが回答を受け取ったあとそこで生じた問題をその1時間後に別のスレで質問していましたが、そういう丸投げの姿勢では技術は身につきません。 アドバイスするくらいのスペースしか有りませんので、アドバイスが可能なようにご自身で多少でも努力されるようお願いします。 こうしたくてこうしましたがダメでした的な状況でのアドバイスなら回答ももう少し具体的かつ明確になるでしょう。
その他の回答 (2)
- kmee
- ベストアンサー率55% (1857/3366)
前のもそうなんですが、やりたいことを、もう少し一般的に書けませんか? queryは a_text= / b_text= で、それを加工している様子はないのに、出力は a= / b= になっています。 あと、消すっていってる意味もよくわかりません。 a=~は最後に送られた a_text=の中身になるように、最新に書き換えていく、ということでよろしいのでしょうか? > #読込んだ行に、$query以外なら、配列に。 > @keep = $_; > @keep = $query 配列になってないし、追加にもなってません。 配列に入らなければ、当然出力もされません。 配列については、解説書や解説サイトで1章さいて説明してあったりするくらい重要なところです。 まずは、基礎を勉強してください。 他にも。 御自身で書いているように, $queryには「●_text=X」が入るわけですよね? とすると > if($_ =~ /$query/){ これは if($_ =~ /●_text=X/){ になる、ということはお理解りですか? つまり、●_text=Xを検索するもので●_textだけを検索するものではないです そも、出力例には●_textなんて行はまったくありません。 > #ファイルを削除する > unlink($open_file_name); 今のままでは +<keep.txt というファイルを消そうとします。 keep.txtではありません。 前回も言いましたけど、最近のPerlならopenは3引数版が推奨ですし、 同じファイル名を使いまわすなら、せめて $file_name = 'keep.txt' open A , '+<' , $file_name ; unlink( $file_name ) ; open A , '>>' , $file_name ; とファイル名とオープンモードは別にした方が間違いは少ないです(事実、一緒にして間違えているわけだし) それから、これも前回言いましたが、CGIでは重要となる「同時にアクセスがあったとき」の対策がまったくありません。 xさんがapple.htmlからa_textを送信したあと、y さんが apple.htmからa_textを送信したら そのあと xさんがbigin.htmlから送信したときの keep.txtのa=はyさんが入力したものになっています。 二人がほぼ同時に送信した場合は、もっと複雑で中身がちゃんとしているかどうかも保証できません。 それでいいのですね?
- Tacosan
- ベストアンサー率23% (3656/15482)
おそらく, while 文が全体として間違っている. 特に @keep = $_; @keep = $query のあたりを見ると「そもそも Perl を理解できていない」としか思えない.