Perlコーディング初心者質問スレ Part 49
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2006/05/31(水) 04:32:28ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0482nobodyさん
2006/06/14(水) 00:39:55ID:???他人が見ても何をやってるか分かるプログラムを書きたいのですが、汚い書き方が身についてしまい困ってます。
簡単なBBS程度のものだと助かります。
0484nobodyさん
2006/06/14(水) 01:20:32ID:???use strict; しつつCPANモジュールを駆使したCGI。
Tropy のソースはタイ変数が使われてて面白い。
http://www.hyuki.com/tropy/
YukiWikiMini は200行ぐらいでWiki書いてる。こちらもなかなか。
http://www.hyuki.com/yukiwiki/mini/index.html
コメントが少ないから、ちょっと難しいかも。
0486nobodyさん
2006/06/15(木) 12:01:24ID:???#!/usr/bin/perl
require './lib.pl';
&test;
[ lib.pl ]
sub test{
print "Content-type: text/html\n\n";
print "test";
}
↑500エラーになる。
[ main.cgi ]
#!/usr/bin/perl
sub test{
print "Content-type: text/html\n\n";
print "test";
}
&test;
↑エラーにならない
requireで読み込むと必ずエラーになってしまうのですが、どうしてでしょうか?
0487nobodyさん
2006/06/15(木) 12:08:41ID:???1;か。
0488sage
2006/06/15(木) 21:58:51ID:gFTNSvnGPerlで
print $cgi -> header(-charset=>"EUC-JP");
と記述したのですが、作ってブラウザーでみると
文字化けしてます。。。
ブラウザーの「表示」→「エンコード」を見ると
西ヨーロッパ言語が設定されてます。。。
これをEUC−JPに直すと文字化けしないのですが、
どうやれば、最初から文字化けしないようにできるのでしょうか?
0489nobodyさん
2006/06/15(木) 22:14:33ID:???多分、HTMLの出力もCGIモジュールを使ってると思うんだけど、出てきたHTML見て見れ。
start_htmlのほうで何も指定しないとlang=en-USのcharset=iso-8859-1になる。
ということで
start_html(-encoding => "EUC-JP", lang => "ja")
0490nobodyさん
2006/06/15(木) 22:18:23ID:???0491489
2006/06/15(木) 22:27:19ID:???ところでふと気づいたけれど、CGIモジュールって
Content-Typeのmetaタグよりtitleのほうが先に来ちゃうのね。
エンコーディングの指定を一番最初に書くことが推奨されてたと思ったけれど・・・
0492nobodyさん
2006/06/15(木) 22:27:38ID:???別にそれでいいじゃん
それぐらい手前で出力しろとか思うわけよ
0493nobodyさん
2006/06/15(木) 23:08:38ID:???なんか文字化けしたままなんですが。。。
レスついたことに(^人^)感謝♪
いわれた辺りをいじってみます。
ありがとうございました。
-------
print $cgi -> header(-cahrset=>"EUC-JP");
print $cgi -> start_html(-title=>$title,
-BGCOLOR => $bg,
-TEXT => $fg,
-encoding => "EUC-JP",
-lang => "ja",
);
-----------
といいつつ
ソース載せてみた。。。orz
0495nobodyさん
2006/06/16(金) 00:24:31ID:???$check = 'デイレクトリ名/ファイル名';
if (-e $check){
&sonzai
}
上記のようにしてやってみましたがどうもifをスルーしてelseのルーチンばかり実行してしまいます。
0496nobodyさん
2006/06/16(金) 01:15:09ID:???0498nobodyさん
2006/06/16(金) 05:13:12ID:???0499nobodyさん
2006/06/16(金) 08:01:47ID:???0500nobodyさん
2006/06/16(金) 08:42:03ID:???0501nobodyさん
NGNG0502nobodyさん
2006/06/16(金) 08:53:11ID:???マルチバイトのファイル名をつける超絶バカは居ないでしょ…
0503nobodyさん
2006/06/16(金) 09:06:03ID:???マルチバイトのファイル名を扱う業務も普通にあるぞ。
もちろんフリーソフトを使って英数字にリネームしてから作業しても構わないわけだが、
全部Perl一本で済ませたいタイプの俺としては非常に面倒いのだ。
0504nobodyさん
2006/06/16(金) 09:07:12ID:???皆さんって最初の大まかな処理分岐ってどうやってますか?
今、テストで1関数で1ファイルで作って
eval{
require '$in{exec};'.'.pl';
&$in{exec};
}
の様に呼ぼうかと思ってるのですが(エラー処理とかばっさり切って略記しました)、
この考え方よらもスマートなやり方があったら教えて頂ければ幸いです
0505nobodyさん
2006/06/16(金) 09:23:19ID:???0506nobodyさん
2006/06/16(金) 09:31:11ID:???まぁperlsynでも読めみたいな。
0508nobodyさん
2006/06/16(金) 10:18:29ID:???0509nobodyさん
2006/06/16(金) 10:20:03ID:???長くなってもわかりやすければそれに越したことはないし、
作成したスクリプトを他人が触る可能性があれば
その方が管理委託しやすいしね
0510nobodyさん
2006/06/16(金) 10:25:22ID:???まあKENTがアレなのは認めるし笑えるんだが、
if 文や local 自体は全然悪くないぞ >>504!
うちには関数 (サブルーチンのことだと解釈したが) ひとつひとつを1ファイルにするとかのが面倒でありえないw
0511nobodyさん
2006/06/16(金) 10:34:11ID:???0512nobodyさん
2006/06/16(金) 12:51:25ID:???サブルーチンを使い回しまくっていると、結局条件分岐
を入れ込む回数が増えて大変だから
HTMLの構文エラー等はなくして欲しいけど
0513nobodyさん
2006/06/16(金) 13:21:21ID:???0514nobodyさん
2006/06/16(金) 13:25:39ID:???0515nobodyさん
2006/06/16(金) 13:57:10ID:???thx 見たことなかったので見てきた。
すごいなこれw
KENTは perl4 とか過去のでも動くように、とかでしょうがないのかなとも思っていたけど、
ここは1年前作った 5.6 以上推奨のでもまったく同じ書き方でしたw
まあわかりやすいっちゃわかりやすい・・・のかな。
0516nobodyさん
2006/06/16(金) 14:18:31ID:???妙にレスポンスだけは良かったりするから困るw
0517nobodyさん
2006/06/16(金) 14:48:05ID:???簡単なものならフルスクラッチしたほうが早い場合もあるし。
0518nobodyさん
2006/06/16(金) 15:16:01ID:???$timp =~ m/^\s*(.*)\s*$/g;
$timp = $1;
というふうにやると $timp が空になってしまいます。
どうしたらよいでしょうか。
0519nobodyさん
NGNG0520nobodyさん
2006/06/16(金) 15:22:19ID:???0522nobodyさん
2006/06/16(金) 16:29:57ID:???今は 出力する前に
if( $flag==1 ){ open(NKFOUT, "| nkf"); }
とやっておいて、出力時に
if( $flag==1 ){ print NKFOUT "ちんこ"; }
else { print "ちんこ"; }
とやろうと思うのですが、ちょっと
0523nobodyさん
2006/06/16(金) 16:34:42ID:???$timp =~ m/^\s*(.*)\s*$/g;
$timp = $1;
というふうにやると $timpo が空になってしまいます。
どうしたらよいでしょうか。
0524nobodyさん
NGNG0525nobodyさん
2006/06/16(金) 16:37:56ID:???正直嬉しかったぞw
0526ヽ(´ー`)ノ ◆.ogCuANUcE
2006/06/16(金) 16:46:15ID:???if ($flag == 1) {
open(my $orig_stdout, '>&STDOUT');
open(STDOUT, '|nkf');
}
# パイプを通して出力
print "ちんこ";
# そのまま出力
print $orig_stdout "ちんこ";
perlfaq5 にある How do I dup() a filehandle in Perl? か、
perlfunc -f open を読むと良い。
0527nobodyさん
2006/06/16(金) 16:59:43ID:???ありがとう。それを参考に
if( $flag==1 ){ open(STDOUT, "| nkf"); }
とやったらだいたいうまくイキました。
0528nobodyさん
2006/06/16(金) 17:31:55ID:???で送ったFと
<input type="text" name="F" value="">
に & を入れて送ったF
って違いますよね?
0529nobodyさん
2006/06/16(金) 17:33:13ID:???&→&
0530nobodyさん
2006/06/16(金) 17:36:21ID:???HTMLなら表示されてる通り送られると思う普通。
0531nobodyさん
2006/06/16(金) 17:45:41ID:???試せばすぐ分かることに対してまじめに答える気にはならん
0532nobodyさん
2006/06/16(金) 17:46:42ID:???use strict;
print "Content-type: text/html\n\n";
my $buffer;
read(\*STDIN, $buffer, $ENV{'CONTENT_LENGTH'},0);
print <<END;
$buffer
<form method="post">
<input type="text" name="111" value="&"><br>
<input type="text" name="222" value=""><br>
<input type="submit">
</form>
END
exit;
下のフォームに&と入れて送信するとあら不思議。
同じような挙動をする文字を知りたいんですがどこかにドキュメントありませんか?
0533nobodyさん
2006/06/16(金) 17:49:12ID:???○<input type="text" name="111" value="&&"><br>
0534nobodyさん
2006/06/16(金) 17:49:56ID:???◎<input type="text" name="111" value="&"><br>
0535nobodyさん
NGNG0536nobodyさん
2006/06/16(金) 18:16:46ID:???$hogeにはブラウザから送られてきたのをデコードしただけの物が入っていて、
print <<END;
<form method="post">
<input type="text" name="hoge" value="$hoge"><br>
<input type="submit">
</form>
こんなことをやって、&が入っていたら&に変わっちゃう…とかいう理由での質問なんじゃないか。
HTMLに流し込む前に実体文字参照に変換汁。
$hoge =~ s/&/&/g;
$hoge =~ s/</</g;
$hoge =~ s/>/>/g;
$hoge =~ s/"/"/g;
# というかこれを知らないなら、頼むから公開するCGIなんか作らないでくれよ…
# XSS脆弱、下手するとScript Insertion脆弱だから…
0537nobodyさん
2006/06/16(金) 18:40:41ID:???ありがとうございます!!
マークアップ記号、Laten-1、ラテン拡張とアクセント記号までは
&があっても直接変換されるようですね。
>>536
そうです、受け取り側での処理に影響するのか?という部分です。
ただし変換自体が問題ではなく、2回以上変換する場合が気になったんです。
というのもHTML::FillInFormの中で変換されてるっぽくて
先に変換かませるとひどいことに・・・
いろいろ試しているうちに上記の実態参照も考慮するべきか悩んだ次第であります。
0538536
2006/06/16(金) 19:30:41ID:???スマソ、ちょっとレベルを低く見すぎた。しかしそういうことは初めに(ry
混乱してるだけだと思うが、そう悩むことではないと思うぞ。
まずCGI側がFormに流し込む、生のテキスト「&」を持っているとする。
HTML::FillInFormは生のテキストをHTMLに変換する。「value="&amp;"」
で、ブラウザはHTMLを解釈して元のテキストに戻してからフォームを表示する。[&]
Submitされると"生のテキストを"URLエンコードなり何なりしてCGIに送り返す。「hoge=%26amp%3B」
で、CGIはURLエンコードのデコード処理をして、生のテキスト「&」を受け取ることになるわけだ。
なぜに二回以上変換するようなことになるのかな…
0539nobodyさん
2006/06/16(金) 19:51:08ID:???非常に混乱しております・・・
2回以上の変換なんですが、実はTTのPluginでFillInFormを使ってるんです。
他で変換しないと生のデータとFillInFormで変換されたデータが混在してしまって。
TTのタグでひとつひとつFILTERつければ回避できそうではありますが
できれば一元管理したいなあと・・・。
クエリを受け取った段階で変換してみたらFillInFormで不具合。
TTに渡す時点で変換すれば良さそうですが、データ構造が結構深いんです・・・
0540nobodyさん
2006/06/16(金) 23:41:05ID:???perlはオブジェクト指向の書き方すると遅くなるのは当然。
「ハードの性能がどんどん上がってるからかまわない」なんて言い訳してるが、
簡単なスクリプトの時にperlでオブジェクト指向の書き方するのはやめたほうがいい。
みんなKENTをけなすが、実はKENTはそれほど悪くないのかもしれない。
こういうと、きっと「コードの再利用が...」「保守のしやすさが....」って言い始めるヤツが必ず出てくる。
でもあの程度の規模だと、動作速度以外にも、理解しやすさとか、動作に必要な条件を考えると
必ずしも悪いと言い切ることは難しいんじゃなかろうか?
0541nobodyさん
2006/06/17(土) 00:24:46ID:???どうやったらあんなコードになるのか理解できない。
0542nobodyさん
2006/06/17(土) 00:25:29ID:???ttp://www.lri.fr/~filliatr/evolution
ごめんなさい。言ってみたかっただけです。
0544nobodyさん
2006/06/17(土) 00:29:58ID:???0545nobodyさん
2006/06/17(土) 00:30:49ID:???> perlはオブジェクト指向の書き方すると遅くなるのは当然。
というソースが欲しい。
0546not 540
2006/06/17(土) 01:52:07ID:???んー、でも、それほど問題になる部分じゃないと思う。
0547nobodyさん
2006/06/17(土) 01:55:18ID:???残念ながら、実行速度に関してだけは >>540 が正しい。
ダミアン・コンウェイの「オブジェクト指向Perlマスターコース」の「はじめに」のvii ページ
「オブジェクト経由でメソッドを呼び出す処理は、通常のPerlサブルーチンを呼び出す場合より著しく低速である」
(「著しく低速」の部分は太字で強調)
手軽に確認するなら
perldoc perltoot
if you wanted fast, you wouldn't be using objects at all
ベンチマークだったら
http://psst.jp/syn/archives/000190.html
オブジェクト指向は遅いというのは共通認識だと思っていたのだが。
だがオブジェクト指向は実行速度を上回るメリットがある。
0548nobodyさん
2006/06/17(土) 02:06:34ID:???親クラスのサブルーチン
親クラスのAUTOLOAD
UNIVERSAL のクラスのサブルーチン
と探すんだから多少は遅くなるのは仕方がない
0549nobodyさん
2006/06/17(土) 02:07:45ID:???オブジェクト指向型プログラミングがバカみたいに遅いのは
インタプリタ言語特有の問題だな
コンパイルすれば、かなりその差はちぢまる
0552nobodyさん
2006/06/17(土) 02:52:44ID:???お前はしないのかもしれないが、他の人間はするんだよ。
第一、スクラッチから書く人間の労力だって圧倒的に違う。
0554nobodyさん
2006/06/17(土) 04:45:08ID:???そそw
いきなりメソッド呼んで、このメソッドはどのファイルにあるのかな?
これかな?誤爆。。なんて事をするくらいなら、1枚板のKENTの方が
改造なんかも手早くやりやすい。
しかもダメと叩かれる部分を修正してやると、さらに体感速度が上がるのも
教材に適してるような…w
0555nobodyさん
2006/06/17(土) 05:44:41ID:4rge2G1Jどこになにがあるのかを説明するより、モジュールリストを共有するほうが効率がいい。
今はひとりでやってるからいいかもしれないがちょっとは先を見ることを勧める。
体感なんてそんな変わらんから、規模の大きい開発の手間のほうが重要。
0556nobodyさん
2006/06/17(土) 05:45:31ID:4rge2G1J0557nobodyさん
2006/06/17(土) 06:31:48ID:???まあ、なんていうか、
それ以外に、
オブジェクト指向では、use とか require したときの速度が遅いのが結構ネックでな。
mod_perl はその時間が減るからいいんだけど。
関数呼び出しが 1.5倍遅い、とか言っても、
それ自体は 1秒間に 45万回 か 64万回 かって違いで、ほとんど気のせい程度の時間でしょ。
問題は何回も実行する、例えば値を取得する param() 呼び出しとかなんだろうね。
それでも param() 程度なら 1000回実行して 0.01 秒か 0.002 秒の違いなんだけど。
つまり、OOPが悪いっていうけど、require とかの時間を考えなければ、そーそー体感で変わるもんじゃないと思う。
実際は他のトコで無駄省いたりして速くするようにすれば、そっちのが変わりそうだよね。
0558nobodyさん
2006/06/17(土) 06:33:38ID:???Jane で書き込むとたまにこうなるんだよなあ・・・。 スペース無駄にしてスマソ。
0559nobodyさん
2006/06/17(土) 07:01:46ID:???作者が再利用しやすいってだけの分割されたスクリプトファイルが
20〜30個って事が結構あるぞ?
しかもKENT製を静的なページを表示するのと同じレベルで実行できる環境で
実行してみると多少の引っ掛かりを感じる。
しかもファイルが分割されてるのにpackageはmainのままだったりするから、
mod_perlで修正することなく動いてもファイルシステム上の位置が変わると
別キャッシュになってメモリを馬鹿食いに。
0560nobodyさん
2006/06/17(土) 07:12:57ID:???> ファイルが分割されてるのにpackageはmain
全然まともなスクリプトじゃねえよw さすが自称www
0561nobodyさん
2006/06/17(土) 07:54:09ID:???こう言う人たまに見かけるよね。
ファイルを分割したりモジュール使うことがオブジェクト指向だと思ってる人。
他にも sub 使えば関数指向だと思ってる人とかさ。
0562nobodyさん
2006/06/17(土) 09:33:44ID:???正規表現について質問です。
たとえば、 'abc' 以外の全ての文字にマッチする場合はどのように書けばいいでしょうか。
acb にはマッチします。
abcaa にもマッチします。
aaabc にはマッチしません。
m演算子の真偽の逆転ではなくて、正規表現内で解決する必要があります。
0563nobodyさん
2006/06/17(土) 09:47:34ID:???/.(?!abc)/ こういうのね
0564562
2006/06/17(土) 10:01:24ID:???前方一致とかじゃ無理な気がする…って思ってたけど、できるんですね。すんません。
なんか正規表現超苦手です。。。頭いたくなるぜ。
/^(.(?!abc))+$/
まだ試してないけどたぶん大丈夫な予感です。ありがとうございますた。
0565nobodyさん
2006/06/17(土) 10:05:24ID:???まあ /^(.(?!abc))+$/ だと 文字列の最初が abc だとマッチしちゃうけどね。なんとかがんばって。
0566nobodyさん
NGNG0567nobodyさん
2006/06/17(土) 12:38:20ID:???キックするのはムリなのは確かだね。必要なファイル読むだけで
しばらくかかるし(笑) レン鯖でCGIしか使えない人は残念でした。
0568nobodyさん
2006/06/17(土) 15:58:17ID:YHZ73blsあんまり複雑なのだと遊びじゃなくなるので。
15分くらいで作れる、簡単だけど面白いのってなんかないかな。
アイデアくだなさいあな。
0570nobodyさん
2006/06/17(土) 16:03:45ID:YHZ73blsなんですかそれ?
ちょっと検索してみますよ。
0572nobodyさん
2006/06/17(土) 16:06:57ID:YHZ73bls以前にショッピングカートを作ったんです。
もう覚えてないのでそのレベルでさえ遊びにならない。
すごい低級になるんですが、低級なりの楽しみ方がないかなと。
少しづつ拡張できるようなのでもいいかなと。
う〜ん。スレ違いっぽ。とりあえずこれにて書込みはおしまいにします。
何かアドバイスが見には来ますのでありがたく。
それでは。
0573nobodyさん
2006/06/17(土) 18:17:27ID:???書き方おかしいけど。
0574nobodyさん
2006/06/17(土) 20:51:25ID:???結城のオリジナルのクローンを書くほうがほうがシンプルだし勉強目的にはちょうどいい。
0575nobodyさん
2006/06/17(土) 21:20:25ID:???そうなの? CPAN コマンドで簡単に入ったんだけど。
0576nobodyさん
2006/06/17(土) 22:42:28ID:???外部モジュールを使わないで UTF8フラグをつけたり、ついてるかどうか検査したりするのってどうしたらいいんですかね?
どっかに誤爆したのは内緒w
0578nobodyさん
2006/06/17(土) 22:58:03ID:???言い忘れ。utf8::以下についてはテンプレの[Perl5.8Unicodeメモ]参照
utf8プラグマと混同しないように。
0579nobodyさん
2006/06/17(土) 23:03:30ID:???え、まぢで? v5.5 とか 5.6 でもできる?
ピンクのサイトの方は見てたんだけど、v5.8 だったkら・・・
0580nobodyさん
2006/06/17(土) 23:17:27ID:???そもそもutf8フラグはありません。
0582nobodyさん
2006/06/18(日) 02:12:27ID:LFB3TFsx$EXPIRES = 3;# アクセスログ保存期間
# 日時の取得
$tm = time;
($sec, $min, $hour, $mday, $mon, $year) = localtime($tm);
$year += 1900;
++$mon;
# アクセス情報の整形
$ln = "$hour\t$min\t$ENV{'REMOTE_HOST'}\t"
. "$ENV{'HTTP_REFERER'}\t$ENV{'HTTP_USER_AGENT'}\n";
# ログファイルの書き込み
$logfile = sprintf(
"$LOGPATH%04d%02d%02d.dat", $year, $mon, $mday);
open(FILE, ">>$logfile")
or die("エラー:ログファイルが開けません");
eval{ flock(FILE, 2) };
seek(FILE, 0, 2);
print FILE $ln;
close(FILE);
# 古いログファイルの削除
$tm -= $EXPIRES * 60 * 60 * 24;
($sec, $min, $hour, $mday, $mon, $year) = localtime($tm);
$year += 1900;
++$mon;
$delfile = sprintf(
"$LOGPATH%04d%02d%02d.dat", $year, $mon, $mday);
if(-e $delfile) {
unlink $delfile;
}
■ このスレッドは過去ログ倉庫に格納されています