Perl コーディング初心者質問コーナー Part26
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
03/07/24 19:48ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
関連スレ
【Perl上級者コーナーPart01】
http://pc2.2ch.net/test/read.cgi/php/1024741312/
CGI: Common Gateway Interface part 11
http://pc2.2ch.net/test/read.cgi/php/1055597189/
【Perl,CGI】参考書籍 第三版
http://pc2.2ch.net/test/read.cgi/php/1030209573/
【 スクリプト改造工房 PART 6 】
http://pc2.2ch.net/test/read.cgi/php/1047806915/
過去ログやお勧めサイトは >>2-10
0160nobodyさん
03/07/27 22:41ID:???>たとえば1MBのログファイルを開け閉めするのと10KBのログファイルを開け閉めするので
>処理時間に差が出たりするのでしょうか?
聞く前に試せよ。その試した結果に疑問があるなら質問しに来い。
0161nobodyさん
03/07/27 22:42ID:???あるんじゃないの?
何のアクセスログか知らないけれど、
ログを切る方法なんていろいろあるでしょ。
apacheのログ?
rotatelogs。。
logrotate。。。
あるいはシェルとか。
0162nobodyさん
03/07/27 22:48ID:???アペンドなら有意な差(特に1Mと10Kなら)はないと思う。実測した事ないので>>160が言ってるように
測定して報告してくれ。
0163nobodyさん
03/07/27 22:57ID:???いえ、apacheのじゃなくてよくある画像を用いたアクセスログです。
あくまで一般的な知識としてどうなのか、と思って訊いてみたんですが。
測定する方法を考えて出なおしてきます。
0164nobodyさん
03/07/28 00:32ID:???DProfとかあんだろ。
0166nobodyさん
03/07/28 01:03ID:???0167159
03/07/28 04:46ID:???空のファイルに対してopen(FH,">>$file")でlocaltimeを書き込んでいくループを
やらせてみたら、ファイルサイズが100KBだろうか1MBだろうが10MBになろうが
処理のスピードは変化無しでした。
まあ考えてみたら>>で書き込むのってファイルを開いてポインタを末尾に移動して
書き込むだけだから、そのファイルが小さかろうが大きかろうが関係無いっぽいけど。
ちなみに同じことを毎回行を配列化→pushで追加→>で新規書き込みっていう
ループでやってみたら、当然処理はだんだん遅くなりました。
16[4-5]のモジュールは使い方よくわかりませんでした。
0168nobodyさん
03/07/28 06:36ID:+imB0DDxサーバー上に掲示板のログが大量にあります。
これらを小さくまとめる&転送速度を上げるために、gzipで圧縮して閲覧可能にしたいと思っています。
gzipの圧縮は1度行えばいいので、Windows上かシェルで行い、サーバー上に置いておくことになりますが、
そのファイル名が、$FORM{url} だとすれば、
print "Content-type: text/html;charset=Shift_JIS\n";
unless($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/){&error($FORM{url}); exit; }
if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /x-gzip/){ print "Content-encoding: x-gzip\n\n"; }
elsif ($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/){ print "Content-encoding: gzip\n\n"; }
if (!open(GURL,"<$FORM{url}")){ &error(1); exit; }
binmode GURL;
@gzipdata = <GURL>;
close(GURL);
print @gzipdata;
exit;
#エラーの場合はURLをリンクで示してダウンロードしてローカルで解凍してもらうよう表示する。
こうなるのかと、とりあえず書いてはみたものの、一度メモりに読むのは避けられないのか、
バイナリ扱うPerl書いたことないからこれでいいのか。
あるいはもっと効率的な方法をご存じの方は教えてください。
0169nobodyさん
03/07/28 11:36ID:???後ろから処理するということはできないでしょうか?
while( <FILE> ) { 処理 }
配列などに入れてしまえばできるのですが、メモリとしてはこちらの方がよいと
思いまして、どうかよろしくお願い致します。
0170nobodyさん
03/07/28 11:44ID:???逆順は難しいと思われ。
一行のバイト数が固定なら色々とやりようもあるだろうが。
可変行の場合、俺はやり方を知らない。
配列でやるんだったら配列の入れ方を工夫するといいかも。
@data = <FILE>;
@data = reverse(@data);
とやるよりも
@data = ();
while(<FILE>){unshift(@data);}
とした方がいいかもしれない。
0171nobodyさん
03/07/28 11:45ID:???0172nobodyさん
03/07/28 12:04ID:???試してないけど。
binmode STDOUT;
my $CRLF = "\x0d\x0a";
my $encoding = $ENV{'HTTP_ACCEPT_ENCODING'};
print 'Content-Type: text/html; charset=Shift_JIS', $CRLF;
$encoding =~ /gzip/ or &error($FORM{url}, exit;
open GURL, '<' . $FORM{url} or &error(1), exit;
if ($encoding =~ /x-gzip/) { print 'Content-Encoding: x-gzip', $CRLF }
elsif ($encoding =~ /gzip/) { print 'Content-Encoding: gzip', $CRLF }
print $CRLF;
print while read GURL $_, 1024; # LENGTH は適宜調整
close GURL;
>>169
http://www.din.or.jp/~ohzaki/perl.htm#File_Reverse
0175nobodyさん
03/07/28 13:21ID:ZypqctSD例えば同じ変数をどこのサブルーチンで使いたい場合はどうするんでしょうか。
いちいち変数の受け渡しをしないといけないんでしょうか。
0177nobodyさん
03/07/28 13:47ID:???174が言ってるように、ファイル名に.gz追加
logfile1.html.gz
HTTP_ACCEPT_ENCODING見てサーバがファイルを選んでくれる。
0178nobodyさん
03/07/28 13:49ID:mZs5gojbour。バージョン古くて使えなければuse vars。
0179nobodyさん
03/07/28 13:52ID:???妙な静的変数
{
my $static;
sub hoge {
}
sub hogehoge {
}
sub hagehage {
}
}
0180nobodyさん
03/07/28 14:33ID:MPvwsvte確認ボタンでその画像がブラウザで確認出来るようにしたいのですが、
良い方法ないでしょうか?
0182nobodyさん
03/07/28 14:41ID:???> 16[4-5]のモジュールは使い方よくわかりませんでした。
使えるようになると便利だぞ。
面倒かもしれんけど、ぐぐってみるなりして使いこなせ。
>>180
送信する前にプレビューってことか?
JavaScriptでフォームからファイルパス取って、IMGに埋め込むとか。
できるかわからんけど。
とりあえずスレ違いなので詳細はそれ系スレで。
0183nobody
03/07/28 21:25ID:0jEUdWDa「じゃんけん」ができるプログラムを作りたいんだけど
何かいい方法ありますか?
当方かなり初心者なんで
print"〜";#って文字を出力することしかできないんですけど。
えーと質問の意味がわからなかったらスルーしてもらってもかまいません。
0184あぼーん
NGNG0185nobodyさん
03/07/28 21:53ID:???まずフローチャートを書け。
それ以降は大学で聞け。
0187nobodyさん
03/07/28 22:03ID:???sleep(1);
print "ぽん\n";
0188あぼーん
NGNG0189nobodyさん
03/07/28 22:10ID:TipKdKzdランダムに3つの中から選ぶプログラムを作って
自分で入力した文字と比較。
結果を出力。でいいんじゃない?
0190あぼーん
NGNG0191nobodyさん
03/07/28 22:25ID:???print "じゃんけん(1=ぐー、2=ぱー、3=ちょき)\n";
<>;chop;
$a = int rand(3)+1;
$hoge = (($a == 1 && $_ == 2) || ($a == 2 && $_ == 3) || ($a == 3 && $_ == 1)) ? '勝ち' : '負け';
print $hoge,"\n";
# お粗末
0192nobodyさん
03/07/28 22:47ID:???0193nobodyさん
03/07/28 22:53ID:???<>;
print ('勝ち', '負け')[int rand 2];
0194nobodyさん
03/07/28 23:08ID:???/⌒ヽ
/ ´_ゝ`)時間的に、ここ笑わないといけないので、笑いますよ・・・
| /
| /| |
// | |
U .U
0195183
03/07/28 23:46ID:xYLAJnZKみなさんいろいろ案出していただいてありがとうございます。
結局自分の力不足で課題内容変えちゃいましたけど。
(みなさんの案は今後参考にさせてもらいます)
>192
今日始めてここに来たんですけど
まぁ課題が出るたびにここで聞くのと同じような根性の持ち主です。
とにかく…評価はCにケテーイぽ(つД`)
0196あぼーん
NGNG0198nobodyさん
03/07/28 23:56ID:???0199あぼーん
NGNG0200183
03/07/29 00:01ID:BcdoPCM8いやしてないし。むしろじゃんけんにしなかったし。
ウザイのでそろそろ逝きます。
0201nobodyさん
03/07/29 00:03ID:???自分の期待する答えがなかったからしなかった(というかできなかった)だけで。
0202nobodyさん
03/07/29 00:25ID:???試したらわかる程度に軽いやつで
0203nobodyさん
03/07/29 01:49ID:???0204168
03/07/29 07:41ID:???ありがとうございました。
Content Negotiationというのがあるとは全く知らず、そのまま表示できたのでびっくりです。
板違いでしたね(汗)
全部圧縮して、リンク先のアドレス変えるだけで問題はすべて解決しました。
大変感謝しております。
0205nobodyさん
03/07/29 08:56ID:pmxt/hz7cgiの中でlocaltimeで、6:00と7:00で処理を分けているんですけど、
crontabの時計とlocaltimeの時計は完全に一致しているんでしょうか?
スクリプトの中で6:00丁度だったらA、7:00丁度だったらBとやっても
crontabが起動した時間が5:58とかだったらAの処理が行われないと思うんです。
0206nobodyさん
03/07/29 10:14ID:???perldoc を調べなさい。
それから
man crontab。
0207nobodyさん
03/07/29 10:15ID:???crontabはcrontableのことだ。
要するにcronの設定ファイル(といっていいかどうかわからんが)
man cron
をすべき。
0208nobodyさん
03/07/29 10:21ID:???0210nobodyさん
03/07/29 10:52ID:???(*´Д`*) マンコロン・・・
0211あぼーん
NGNG0212nobodyさん
03/07/29 11:44ID:pmxt/hz70213nobodyさん
03/07/29 11:47ID:MFa+8P58<STDIN>; ではうまくいかないので下のコードのようにしましたが、
2つ目のwhileを無駄に回さなくてもいいようにする方法はありますかね?
今のところsleepを入れるくらいしか思いつかないです。
sub {
my $sig = 0;
local $SIG{INT} = sub {$sig = 1;};
while (1) {
# ここに$interval(分)ごとにする処理
while (time() % ($interval * 60)) {
sleep (1);
return 1 if($sig);
}
}
}
0214あぼーん
NGNG0215nobodyさん
03/07/29 12:00ID:???1 TTYをnon-canonicalモードにする。
プラットフォーム依存。モジュールあるかも。
2 特定のキーでシグナル発生させる。
0217nobodyさん
03/07/29 15:52ID:???を参考にhttpクライアントを作ってみたんですが
どうも404が返ってくるところが多くて不思議なのですが
どういうことなのでしょう?
例えば参考にした上のページは見れるんですが
自分のISPのページは
Http://host/~user/index.html でリクエストすると404で
Http://host/~user/ なら大丈夫なんです。
(勿論ブラウザなら両方OKです。)
ソースへ
print SOCKET "Host:$host:$port\r\n";
を追加したら大抵取得できる様になったんですが
それでも100%でないので納得できないのです。
何が不足しているのでしょうか?
サッパリ意味が解らないのでご教授お願いします。
0219217
03/07/29 16:39ID:???バーチャルホストへは
print SOCKET "Host:$host:$port\r\n";
で対応できているんですよね?
何だか原因はスペルミスだけだった気がしてきました。
0220nobodyさん
03/07/29 16:53ID:???>>217 サーバーの DirectoryIndex (クライアントがディレクトリをリクエストしたときに調べるリソースのリスト)確認しろ。
0222nobodyさん
03/07/29 19:38ID:71pkcqEp(゚Д゚ )ハァ?
それで返ってくるのは403だろ。氏ねや
0223あぼーん
NGNG0224nobodyさん
03/07/29 19:55ID:???0225nobodyさん
03/07/29 21:36ID:???alarm使って、キー待ちにしたらどう?
time値の0秒ジャストで動かせないけど。
local $SIG{ALRM} = sub { die 'timeout' };
...
my $c = &keywait(1);
...
sub keywait
{
my $interval = shift;
eval{
alarm($interval*60);
<>;
alarm(0);
};
if ($@){
alarm(0);
($@ =~ /timeout/) or die;
return(0);
}
return(1);
}
0227nobodyさん
03/07/29 23:46ID:Y5f15xmJ#$buffer = $ENV{'QUERY_STRING'};
@pairs = split(/&/, $buffer);
foreach (@pairs) {
($key, $val) = split(/=/);
$in{$key} = $val;
}
ここまでやった後で連想配列の中身を見る方法を教えてください。
どんなkeyが入ってるか知りたいのです。それによって処理を分岐するので。
初歩的な質問ですみません。
0229nobodyさん
03/07/29 23:48ID:???0230nobodyさん
03/07/29 23:48ID:???foreach $key ( sort( keys %ENV ) ) {
print "$key = $ENV{$key}\n";
}
0233あぼーん
NGNG0234nobodyさん
03/07/30 00:01ID:KKMTj9U0$name = 'c:\windows\system32';
$i = 0;
while($name =~ /\\/g){
$i+=1;
}
@match = ();
for($n=1; $n<=$i+1; $n++){
$a = '$path'.$n;
push(@match,"$a");
}
@match = split(/\\/,$name);
foreach $col (@match){
print "$col<br>";
}
がんばってこんな感じになりました。
けっこう長いです・・サブルーチンになりそう・・・
もっと簡潔な方法あれば教えてください。
0235234
03/07/30 00:06ID:KKMTj9U0$a = '$path'.$n;
push(@match,"$a");
これは、
push(@match,"%n");に変えます。
配列の全値をjoinでスカラ($match)に代入
そして、($match) =split・・・・
ってやるつもりだったんですが、$matchが展開されないってことに気づいて、
リファレンス良く見ると、そのまま配列でsplitできることがわかって、
$pathっての消すの忘れてました。
0236234
03/07/30 00:06ID:KKMTj9U0○ $n
何回もすいません。
0237nobodyさん
03/07/30 00:08ID:???>>1の
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
これを読め。結局何がしたのが伝わってこない
0238nobodyさん
03/07/30 00:08ID:???○結局何がしたいのか伝わってこない
0239234
03/07/30 00:09ID:KKMTj9U0簡潔な方法がないか聞きたかったんです。
けっこう長いから・・・
0241234
03/07/30 00:10ID:KKMTj9U0簡略なソースを求めるスレでないんですね。
どうもすいませんでした。
0243nobodyさん
03/07/30 00:13ID:???ただ単にソースをダラダラ書かれても困るだけ。
このスレの解答者はソース解析屋でもないんだから
0244あぼーん
NGNG0245nobodyさん
03/07/30 00:14ID:QkXS28T1ErrorメッセージがInternal Server Errorだけじゃ捗りませんよね。
0246nobodyさん
03/07/30 00:15ID:???0247234
03/07/30 00:17ID:KKMTj9U0ええと、このソースは、フォームから「文字列」と、「分解の基準になる文字列」(なんか分かりにくいかな・・
split(/aa/,"")←ここのaaの部分です。
で、フォームからだと、だれがどんな文字列もってくるかわからないでしょ?
だから、当然分解数も違う。
それで、分解数がはじめから分からなくても、ちゃんとsplitで分解する
っていうのが上のスクリプトなんです。
あぁ、説明下手で伝わらなかったらゴメン
0248234
03/07/30 00:20ID:KKMTj9U04行目の「で」は「受け取って、splitで分解するスクリプトなんです。」ですね・
なんか日本語変になってる
0249nobodyさん
03/07/30 00:20ID:???0251234
03/07/30 00:24ID:KKMTj9U0>>234のスクリプトは、フォームから「文字列」と「分解の基準になる文字」を受け取って、
それをsplitして表示する、というものです。
でも、フォームから送られてくるのは人によってまちまちだし、当然分解する数も違うので、はじめっから
($a,$b) = split(/$bunkaimojiretu/,"$mojiretu");なんてできません。
だから、上のようにまず、whileで「分解の基準になる文字列」の数を調べて、
次に、その数+1個分の値がある配列を作ります。
そして、その配列を分解
こうすれば、分解数がわからなくても、ちゃんとsplitしてくれる、そういうスクリプトです。
0252234
03/07/30 00:26ID:KKMTj9U0どうもソースが長いなぁ、と思い、簡略化できないかと聞いてみた次第です。
お手数かけてすみません。これでマシな日本語になりましたか?
0253nobodyさん
03/07/30 00:27ID:???なんでそんなことをする必要があるのか全然わからん。
@pairs = split /\&/, $STDIN;
foreach ( @pairs ) {
($k, $v) = split /=/;
$form{$k} = $v;
}
これでは何故いかんのか?
0254nobodyさん
03/07/30 00:29ID:???$name = 'c:\windows\system32';
foreach (split(/\\/,$name)) {
print "$_<br>";
}
もう飽きた。
0256234
03/07/30 00:29ID:KKMTj9U0僕がやっているのは、ブラウザからなんですよ。DOS窓じゃないんです・・・
0257213
03/07/30 00:30ID:???0258nobodyさん
03/07/30 00:30ID:???0259234
03/07/30 00:30ID:KKMTj9U0えと、この場合は、フォームからの文字列が、たとえば「c:\windows\system32」の場合の話ですよ〜
ってことです。
なにも言ってなくてスイマセン。
0260234
03/07/30 00:31ID:KKMTj9U0split(/$cut/,$name)くらいにしておけばよかったです。
誤解を招くようなこと書いてすいません。
■ このスレッドは過去ログ倉庫に格納されています