Perlコーディング初心者質問スレ Part 54
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2007/02/10(土) 19:21:23ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc10.2ch.net/test/read.cgi/php/1164519503/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0002nobodyさん
2007/02/10(土) 19:23:04ID:???[プログラミング自体の経験が無い奴はまずココを読め]
Perlプログラミング講座: ttp://www.site-cooler.com/kwl/perl/
[本]
リャマ: ttp://www.oreilly.co.jp/books/4873111269/
駱駝: ttp://www.oreilly.co.jp/books/4873110963/
Effective Perl: ttp://www.ascii.co.jp/books/detail/4-7561/4-7561-3057-7.html
クックブック: ttp://www.oreilly.co.jp/books/4873112028/
[オンラインマニュアル] (追加)
最新のドキュメント: ttp://search.cpan.org/dist/perl-5.8.8/
perl5.8.xのドキュメント(一部): ttp://www.kt.rim.or.jp/~kbk/perl-5.8/
perl5.005_03 のドキュメント: ttp://www.kt.rim.or.jp/~kbk/perl5.005/
日本語ドキュメント検索: ttp://www.cpan.jp/search.cgi
perldoc.jp: ttp://www.perldoc.jp/
Perldoc.com: ttp://www.perldoc.com/
0003nobodyさん
2007/02/10(土) 19:23:37ID:???[モジュール]
CPAN.com: ttp://search.cpan.org/
河馬屋二千年堂: ttp://homepage3.nifty.com/hippo2000/
[テクニック]
Perlメモ: ttp://www.din.or.jp/~ohzaki/perl.htm
Perlのページ: ttp://homepage1.nifty.com/nomenclator/perl/
Perlの小技: ttp://homepage3.nifty.com/hippo2000/perltips/index.htm
[Perl5.8Unicodeメモ]
ttp://www.pure.ne.jp/~learner/program/Perl_unicode.html
ttp://www.namazu.org/~tsuchiya/perl/perl-5.8.html
ttp://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html
0004nobodyさん
2007/02/10(土) 19:25:07ID:???CGI: Common Gateway Interface part 13
http://pc8.2ch.net/test/read.cgi/php/1126436361/
【Perl,CGI】参考書籍 第三版
http://pc8.2ch.net/test/read.cgi/php/1030209573/
【Perl】ファイルロック(排他処理)について語ろう
http://pc8.2ch.net/test/read.cgi/php/1024795138/
★負荷軽減対策委員会(Perl、PHP)★
http://pc8.2ch.net/test/read.cgi/php/1034645635/
CGIに依存しないPerlの話題一般/Part2
http://pc8.2ch.net/test/read.cgi/php/1030548610/
★三 【 スクリプト改造工房 PART 9 】 ★三
http://pc8.2ch.net/test/read.cgi/php/1143834740/
【 スクリプト改造依頼スレ 】(丸投げ) part6
http://pc10.2ch.net/test/read.cgi/php/1157787046/
0005あぼーん
NGNG0006あぼーん
NGNG0009nobodyさん
2007/02/11(日) 11:51:13ID:uXIy6Xmt例
0.57 * 100
0.07 * 100
IE6のJavaScriptだと上の場合 56.99999 となりズレます。
いろんな数値をperlで試しており、今のところズレは起きていないのですが perl は大丈夫なのでしょうか?
0010nobodyさん
2007/02/11(日) 12:07:58ID:uXIy6Xmt以下のようにすると 57, 56 と結果が返されます。
---------------------------------
print 0.57 * 100;
print int(0.57 * 100);
---------------------------------
0.57 * 100 の結果は "57" に見えるけど本当は違うのでしょうか?
0011脱帽
2007/02/11(日) 12:50:44ID:???0012nobodyさん
2007/02/11(日) 14:24:00ID:???0.57 * 100 → 57 * 100 / 100
0013nobodyさん
2007/02/11(日) 16:04:38ID:uXIy6Xmt有難うございます。bignum.pmというのは知らなかったです。
Math::BigFloat をよく使うのですが、大量の計算をする場合にはスピードがだいぶ気になります。
10や100などの計算だけでも..と思ったのですが。
>>12
すいません。私には何が言いたいのか理解できません(>_<)
もう少し教えて頂け無いでしょうか。
0014nobodyさん
2007/02/11(日) 16:06:28ID:???0015nobodyさん
2007/02/11(日) 18:39:39ID:???0016nobodyさん
2007/02/11(日) 22:17:14ID:???放置すればよろし。
0018nobodyさん
2007/02/12(月) 02:02:34ID:???0019nobodyさん
2007/02/12(月) 02:52:50ID:???つ http://docs.sun.com/source/806-4847/ncg_goldberg.html
熟読しとけ。な?
0020nobodyさん
2007/02/12(月) 14:57:27ID:EeKO4sif<INPUT TYPE="text" NAME="data" VALUE="a">
<INPUT TYPE="text" NAME="data" VALUE="b">
<INPUT TYPE="text" NAME="data" VALUE="c">
のようなフォーム内のデータを
@formdata = ('a','b','c');
というように取得したいんですが、
%form = $cgi->parse_form_data();
@formdata = $form{'data'};
だと取得できませんでした。
そもそも配列をそのまま取得することはできないんでしょうか?
情報が載っているサイトだけでも良いのでアドバイスお願いします。
0021nobodyさん
2007/02/12(月) 15:17:31ID:???002220
2007/02/12(月) 15:27:01ID:???レスありがとうございます。
そういうオチはないです。
$formdata = $form{'data'}
にしても
@formdata = $form{'data'}
にしてもも同じ値(リファレンス?)が1つだけ返ってくるだけです。
ちなみに
$formdata = split(/ /,$form{'data'});
とかもやってみましたが、こちらは何も返ってきませんでした(当然ですが)。
0023nobodyさん
2007/02/12(月) 17:09:55ID:???> 同じ値(リファレンス?)が1つだけ返ってくるだけです。
そこまで分かってて何故デリファレンスしないんだ。
http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.html
@formdata = @{ $form{'data'} };
002421
2007/02/12(月) 17:29:44ID:???俺を含めないでくれ。
002520
2007/02/12(月) 20:57:49ID:???あ・・・。お恥ずかしい。
その通りですね。
自分なりにデリファレンスやってみたつもりが
全然違う書き方してたみたいです。
デリファレンスの書き方で混乱しないように勉強します。
ありがとうございました!
0026nobodyさん
2007/02/13(火) 15:50:27ID:Kq8fojs+perlもPostgreSQLの文字コードもEUCで保存しています。
どのように文字をエスケープすればいいのか検索して調べてもわかりません。
よろしくお願いいたします。
0027nobodyさん
2007/02/13(火) 16:14:50ID:???002826
2007/02/13(火) 18:34:04ID:Kq8fojs+よろしければもう少し詳しくお願いできないでしょうか?
0029nobodyさん
2007/02/13(火) 19:14:11ID:???処理中に文字化けしているのか、出力時に文字化けしているのか
そもそも文字化けなのか?DBに入らないのか?
文字化けならJcode::CP932(ただし要Jcode.pm上書き)か
WebだけならEncode::XMLCREFがいいんじゃないかと思いました
0030nobodyさん
2007/02/13(火) 21:14:34ID:???BBQ規制に関してです。
BBQ規制に巻き込まれた人を規制からはずすということをしたいのですが、
そのために
"allowhost.txt"に書き込まれたホストを一行ずつ読み込んで一致すれば規制を抜ける
ということにしたいです。
以下のソースの書き方では
串を入れるとBBQ規制には引っかかるのですが、
同じ串を"allowhost.txt"に書き込んでも規制を抜けません・・・。
どういう描き方が適当なんでしょうか?
0031nobodyさん
2007/02/13(火) 21:17:02ID:???sub checkProxyList {
###ホスト取得###
$RADDR = $ENV{'REMOTE_ADDR'};
$host = $ENV{'REMOTE_HOST'};
$addr = $ENV{'REMOTE_ADDR'};
if ($host eq "" || $host eq "$addr") {
$host = gethostbyaddr(pack("C*", split(/\./, $addr)), 2);
}
if ($host eq "") { $host = $addr; }
### $hostが"allohost.txt"と一致しているか調べる###
open(ALLOWHOST,"allohost.txt");
@allowhost = <ALLOWHOST>;
close(ALLOWHOST);
foreach $allowhost (@allowhost) {
$allowhost =~ s/\r//;
$allowhost =~ s/\n//;
$search = index($host, $allowhost);
if($search >= 0){
$flag = 1;
}
}
0032nobodyさん
2007/02/13(火) 21:17:27ID:???###BBQ規制###
$RADDR =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
$query_addr = "$4.$3.$2.$1.niku.2ch.net";
$address = join('.', unpack('C*', gethostbyname($query_addr)));
if ($address eq '127.0.0.2'){
if($flag == 1){
print "Content-Type: text/html\n\n";
print "規制を抜けました";
exit;
}
else{
print "Content-Type: text/html\n\n";
print "公開Rroxyからの投稿は受け付けていません!";
exit;
}
}
$flag = 0;
return 0;
}
my $Resolve = Net::DNS::Resolver->new(
udp_timeout => 30, # お好きな時間(タイムアウト)に♪
);
# --- BBQ・・・
my $BBQ_Status;
my $query = $Resolve->search(sprintf qq|%s.niku.2ch.net.|, join '.', reverse split( /\./, $IP_Address));
if ($query) {
foreach my $rr ($query->answer){
next unless $rr->type eq "A";
$BBQ_Status = $rr->address;
last;
}
}
print qq|-- BBQ --\n|;
printf qq|\t$IP_Address -> %s\n|, $BBQ_Status
? "Roasted(-_-)"
: 'None(^-^)';
風呂敷確認君より抜粋♪
ほへ?
エスパーさんぢゃないのでよくわかんないけれども、exit;しているからヂャネ?
0036nobodyさん
2007/02/13(火) 23:11:09ID:???にしないと、なんの為にフラグ用意してるのやら
003726
2007/02/14(水) 11:57:59ID:mjFZ4k3U"��"などの文字をDBに入れようとすると、DBからのエラーが帰ってくるんです。
Webminから直接DBのデータを操作して"��"を入れるとすんなりと入るので、
perlで入れるときは文字に何らかの処理をかける必要があるのかと思ったのですが。
入力するデータはCSVファイルで、jcode.plを使ってSJIS→EUCへエンコード後に、SQLコマンドを実行してDBに書き込んでいます。
"��"などの文字が入っていなければ、エラーはないのですが、入っているとエラーが帰ってきてDBへの書き込みができません。
スクリプトの文字コードはEUCで、perlのバージョンが5.6.1なのです。
0038nobodyさん
2007/02/14(水) 12:35:03ID:???0039nobodyさん
2007/02/14(水) 12:39:29ID:???書き込もうとしてうまくいかないバイト列を比較してみてはどうか。
君の変換がおかしいのか、もっと先に問題があるのかの切り分けにはなる。
0040nobodyさん
2007/02/14(水) 14:04:28ID:???0041nobodyさん
2007/02/14(水) 14:27:20ID:???# そもそもeuc-jpをやめて全部utf-8に…ゲフンゲフン
004240
2007/02/14(水) 14:41:35ID:???すまんこ。euc-jp で表現できることを確認しますた。
0043nobodyさん
2007/02/14(水) 14:49:15ID:???はしごだかはIBM拡張文字なのでなんらかの拡張が必要なんじゃない?
拡張したのもeucと呼ぶ人がいるけれども、拡張の方法も一通りでは
ないからどれのつもりで言ってるか気をつけないといけない。
ttp://msyk.at.webry.info/200511/article_2.html あたり参照。
5.6はいい加減捨てて5.8.x+Encode::EUCJPMSを使う方がいいん
じゃないかと思う。
0044nobodyさん
2007/02/14(水) 14:55:18ID:RW6nNThJperlって難しすぎる。
004540
2007/02/14(水) 15:07:46ID:???秀丸で、「高 ��」を euc で保存 (euc.txt)
秀丸で同ファイルを開くと、ちゃんと読める
$ hexdump -C euc.txt
00000000 b9 e2 20 fc e2
以下は、utf-8 な fc6 に ssh して実行。
$ iconv --from euc-jp --to utf-8 euc.txt
高 iconv: 位置 3 で不正な入力シーケンスがありました
$ cat euc.txt | perl -MEncode -ne 'print decode("euc-jp", $_);'
Wide character in print at -e line 1, <> line 1.
高 ?
0047nobodyさん
2007/02/15(木) 00:36:29ID:???どうにも困った事がおきたので質問させてもらいます。
チャットには参加者一覧が表示されます。携帯からチャットにアクセスすると、その
参加者一覧に自分の名前がいくつも表示されるという不具合が起きました。ログを見る
と携帯電話は数分でIPが変わっていて、それをスクリプトが別端末からのアクセスだ
と誤認したのが原因でした。(最終アクセスから5分経つとそのIPの参加者の名前はリ
ストから削除します。)
そういえば2chは携帯で書き込んでも毎回同じIDだなと思い、何度かfusianasan
をしてみるとIPは(たぶん)変わっているにも関わらず、全て"07012360463529_vi"とい
う謎の文字列が出てきました。2chは同一端末からのアクセスをなにかエロい事をして
認識しているらしいです。
参加者リストに同じ名前が複数あるときは一つにまとめようかと考えていますが根本
的には解決していないので、気持ち悪いので、何かいい案を下さい。
# KENT WEBのCOMCHATをベースに改造してつかっています。
# ttp://www.kent-web.com/chat/comchat.html
0048nobodyさん
2007/02/15(木) 00:40:35ID:???教えていただきたいのですが、よろしくお願いします。
use strict;
use warnings;
use CGI::Carp qw/fatalsToBrowser/;
この3行をソースコードのはじめのあたりに加えると
Global symbol "$xxxx" requires explicit package name at ・・・
こういうエラーが出てきました。
・グローバル変数の探し方は、この方法で大丈夫でしょうか?
・この出てきたグローバル変数の中で、”値の変化しないグローバル変数はそのまま”
”値の変化するグローバル変数にmyを付けて”、動作も矛盾しないようなコードに
直せばよいのでしょうか?
マルチスレッドのようなイメージで考えればよいでしょうか。
0049nobodyさん
2007/02/15(木) 01:03:55ID:???0050nobodyさん
2007/02/15(木) 01:28:23ID:KpCoXSAWセッションID(の類)をリロードの時に送信するとか。
リロード方法によってはIDの伝達途切れるから、
名前+UAくらいで判別するのも悪くはないと思う。
2chが何やってるかは知らない
>>48
他言語の経験あるならその方針で大丈夫
0051nobodyさん
2007/02/15(木) 02:02:42ID:???助けてやってください。
さくらのシェルで、viでこんなのを書きました。
#!/usr/bin/perl
print "Hello World!\n";
そしてchmod 755して、ブラウザからhttp://foo.jp/var.cgiとやったらサーバエラーになるんです。orz
私は何か根本的な事を知らないのでしょーか?
0052nobodyさん
2007/02/15(木) 02:11:09ID:???ActivePerlと04WebServerでもダウンロードしてローカルでやんなさい。
0054nobodyさん
2007/02/15(木) 02:34:06ID:???助かったの?
CGIの場合少なくとも最初に
print "content-type: text/html\n\n";なり、
print "content-type: text/plain\n\n";なりの出力が必要。
確かに根本的な事。
ローカルの方が作業もしやすいよ。
0055nobodyさん
2007/02/15(木) 02:50:34ID:???動きますた!
そんな類のこったろうと思いましたが、具体的に何書いて良いかがわかりませんでした。(^^;
これでまっとうな勉強が出来そうです。
>>52
いやーローカルの鯖でシェルからperl ./var.cgiしたら文句なく動いてるのに、cgiとして動かしたら何故動かない!とテンパってたんです。(^^;
生のperlとCGI経由の違いが解ってようやく前に進めそうです。
0056nobodyさん
2007/02/15(木) 06:55:48ID:???VMware server と、適当な Linux でいいんじゃないの?
005753
2007/02/15(木) 08:12:01ID:???SpeedyCGIなんとか入れてみました。ネットで調べたところ、
「使用し終わったグローバル変数がそのまま再利用されるため、
変数にゴミが入った状態になります。 グローバル変数の初期化が前提です。」
とありました。
i=0; i++; i++; i++; i++; i++; print("i");
i=0;と初期化して、5回足しています。
1,2,3,4,5と順調に加算されて、printする瞬間iを参照したら、
5でなくi=3だったということには、ならないのでしょうか。
使用し終わったグローバル変数がそのまま再利用
ということなので、ひとつのプロセスが使用中のグローバル変数は、
他のプロセスで再利用(参照)されないで、新しいプロセスは新しいグローバル変数が
割り当てられるんでしょうか。(わかりづらくてすみません)
初期化するだけで大丈夫、という仕組みが難しいです。
解説しているページやアドバイスなどお願いします。
0058nobodyさん
2007/02/15(木) 09:07:33ID:???それはEZ番号ではないですか。auでEZ番号を通知するモードにしていると、公式サイトでなくても
環境変数$ENV{HTTP_X_UP_SUBNO}から取得できます。端末の同定には都合がいいですが、
他のキャリアでは通用しないと思います。やはり、最初のアクセスの時にセッションIDを発行して
引き回すしかないのでは?
0059nobodyさん
2007/02/15(木) 10:55:43ID:???おっかしいなーとおもったらIPマッチ使ってた
0060nobodyさん
2007/02/15(木) 11:25:12ID:???携帯は固有番号をもっている。2chはそれを取得している。IPアドレスはリクエスト毎に可変で、しかも1ページの取得に複数のIPを使うこともある。
固有番号は、(たしかEzWeb以外は)ユーザが許可したらHTTPヘッダに埋め込まれ、仕様は各ベンダーサイトで見れる。
>>57
#!〜から始まる1行目(名前を忘れた)に変数を初期化するオプションがあったはず
0061nobodyさん
2007/02/15(木) 14:47:43ID:???auのケータイは常に EZ番号 (旧サブスクライバID) という個体識別番号を送信している。
Softbank もデフォで全てのサイトに送信されると思った。
DoCoMoは確か投稿時に確認画面がでて、(,,゚Д゚)∩ハイッ!! を押すと個体識別番号が送信される。
携帯から fusianasan を安易にやることは避けたほうがいいし、
Webアクセスもなるべく自宅に設置したGWなどを使うか、全てのサイトで個人情報を入力しないほうがいい。
これは解約まで基本的に不変な情報であり、極めて危険。
ショッピングサイトの情報が漏洩したら、ワンクリサイトにアクセスしただけで、ワンクリ業者が住所などの個人情報を入手できることになるから。
006247
2007/02/15(木) 21:15:09ID:???固有番号を使うのはいろいろ面倒だったのでセッションIDを実装することにしました。
006353
2007/02/15(木) 23:45:03ID:???レスありがとうございます。
マルチスレッドみたいに、ひとつのグローバル変数を参照している
わけではないんですね。はじめだけ初期化すれば、あとは他のプロセスから
影響ないんですね。ふむふむ。
>#!〜から始まる1行目
さっそく調べてみます。ありがとうございました。
0064nobodyさん
2007/02/16(金) 00:11:07ID:???【質問の概要】
Perlスクリプトを記述する際の文字コード種類をUTF-8とした場合の、文字置換の考え方に対する質問です。
【質問の内容】
下記のソースを書いたとします。
#------------------
$char = "aBc";
$char =~ s/a/a/g;
print $char;
#------------------
上記ソースをShift-JISで記述した場合、全角の"B"の文字コードは"8261"のため、半角の"a"の文字コード"61"で2バイト目が置換されてしまい、文字化けしてしまいます。
これと同一のソースをUTF-8で記述すると、半角の"a"が、全角の"a"に置換されます。
この結果を見る限り、UTF-8でソース記述すると、文字置換の際に、1バイト、2バイト目の誤置換を意識しなくてもいいように思うのですが、この認識は間違っているでしょうか?
もし、認識違いの場合は、UTF-8の場合、どのような文字の並びで誤置換が起こるのか、教えていただけると幸いです。
申し訳ありませんが、ご教授ください。
0065nobodyさん
2007/02/16(金) 00:55:50ID:MoploLOUPerl で、以下のCGIを作りました。
1)CSVファイルをアップロード
2)アップロードしたファイルを処理
3)処理したファイルのリンクを表示してダウンロード。
ところが、2)が重くて待たされるので、(MAX数分)
プログレスバーを表示しようと思うのですが、
どうやったらいいか・・・・。
ちゃちゃっと簡単にできる方法があればよろしくお願いします。m(_ _)m
0067nobodyさん
2007/02/16(金) 01:41:11ID:???その結果を見ただけで意識しなくてもいいと判断する事は出来ないが、
正しいUTF-8ではそのような問題や、EUC-JPで良く発生するような
ずれてマッチする問題は起こらないことが保証されている。
参考資料: RFC2279(obsoleteだがUCS-4の範囲を全て表現できるため), RFC3629
というのもUTF-8というエンコーディングは面白い構造をしている。
まずASCIIの範囲はそのままASCIIのために割り当てられていて、
マルチオクテット文字には出現しない。これはEUC-JPと同じ。
で、問題のマルチオクテット文字の表現なのだけれど、
nオクテットで表現されるUTF-8文字は、最上位ビットから
nビット1が連続した後に0が来るようになっている。
全ての非ASCIIのUTF-8文字は2byte以上で表現されるので、
これは1オクテット目が10xxxxxxにならないということ。
そして、2オクテット目以降は上位2ビットが必ず10になっている。
これらによって、マルチオクテット文字中にASCII文字が登場したり、
他のUTF-8文字にずれてマッチするようなことがないことが保証できるわけだ。
さて、ここまではUTF-8に対する一般的な話だが、実はPerl(5.8以降、5.6は怪しい)は
UTF-8を内部エンコーディングとして正式にサポートしている。
文字列にはUTF-8フラグというものが用意されており、
マルチオクテット文字を1文字として扱うことが出来るようになっている。
この辺の話はテンプレ>>3の[Perl5.8Unicodeメモ]にあるサイトが詳しいので、
必要ならとりあえずそっちを読んでくれ。
0070nobodyさん
2007/02/16(金) 06:38:18ID:MoploLOU数倍ならば高速化できますが、100倍はムリだとおもいます。
処理内容は以下に記載。
1)CSVを1行を読み込み。
2)対応するWEBページのURLを作成。
3)上記URLをもとにWEBページをダウンロード。
4)ダウンロードした情報をCSVに付加。
処理時間は 1行あたり凡そ1秒。
既にダウンロードした情報はDBにキャッシュしていますが、
情報量の関係で
「新規にWEBページをダウンロードしなければならない」場合が
発生するのです。
0071nobodyさん
2007/02/16(金) 09:57:57ID:???例えば、AjaxとかCommetとかFlashで何秒おきかに進捗状態を取得して表示するとか。
かなり面倒なことは確か。
0072nobodyさん
2007/02/16(金) 10:28:08ID:???0073nobodyさん
2007/02/16(金) 14:30:20ID:???007464
2007/02/16(金) 19:29:33ID:???丁寧な説明ありがとうございました。
>その結果を見ただけで意識しなくてもいいと判断する事は出来ないが、
その通りですね、すみません・・・
007565
2007/02/16(金) 23:38:29ID:MoploLOUどうもです。
やはり ajax ですか・・・、調べてみます。
0076nobodyさん
2007/02/17(土) 01:22:16ID:???使ったことないけど、シンプルな進捗表示でいいなら
multipart/x-mixed-replace でさくっとできそうな気がする
007776
2007/02/17(土) 01:32:05ID:???やったことある方法では「<script> statusbox.value = "現在5件処理完了"; </script>」
的な1行javascriptをautoflushでprint。
0079nobodyさん
2007/02/17(土) 20:47:43ID:???my @file = <FILE>;
これより効率の良い方法ありますか。
ファイルの中身は最大で100KBです。
共有鯖なので心配で使えません。
0080nobodyさん
2007/02/17(土) 21:23:25ID:???0081nobodyさん
2007/02/17(土) 21:33:47ID:???最終的に何がしたいのか、および何の効率かによる。
メモリ効率を気にしていて、「ファイルの中身を」丸ごと「配列に入れたい」のなら、
その方法だとデータサイズの2倍程度メモリを消費して、
1行ずつpushで代入する方法だとデータサイズと同じ程度だったが。
(perl5.8.7 on FreeBSD5.4調べ)
本当にやりたい事を考えずに配列に代入する効率だけ考えるのは本末転倒というものだ。
0082nobodyさん
2007/02/17(土) 21:44:02ID:???0083nobodyさん
2007/02/17(土) 21:55:29ID:???(ファイルのフォーマットは先頭が数字で固定)
my @log = <FILE>;
my($start,$end) = hoge(); #ユーザーの入力による数字
my $new = ( $log[$#log] =~ /^\d+/s ) ? $& : 0;
my $old = ( $log[0] =~ /^\d+/s ) ? $& : 0;
$start = $old if( $old > $start );
$start = $new if( $start > $new );
$end = $old if( $old > $end );
$end = $ned if( $end > $new );
$end = $start if( $start > $end );
my @choice = print_request_lines(\@log,$start,$end);
sub print_request_lines {
my($log,$start,$end) = @_;
my $count = $start;
$end = $count unless($end);
foreach ( @$log ) {
if ( /^\Q$count\E/s ) {
print;
if ( $count >= $end ) {
last;
}
else {
$count++;
}
}
}
}
あとあとはこんな処理です。長いので一応簡潔にまとめたつもりです。
read(FILE,my $hoge,-s FILE);とか?
気になるのは鯖の負荷です。一日2万弱アクセスあります。
008481
2007/02/17(土) 22:00:24ID:???my @choice = ...
あたりはまとめミスですorz
0085nobodyさん
2007/02/17(土) 22:02:22ID:???83でした。すみません
0086nobodyさん
2007/02/17(土) 22:28:50ID:???指定される範囲は通常データ全体に比べて非常に小さいものかな?
番号がソートされて並んでいるなら二分探索が有効。O(log n)に出来る。
行頭探すのがちょっと面倒だがなー。データ構造を変えることが可能ならば、
あらかじめ番号に対してオフセットを記録しておくような簡単なindex付けを行っておくのが吉。
0087nobodyさん
2007/02/17(土) 23:07:21ID:???指定される範囲は予想ではデータ量の2割りくらいがメインです。
10割りの時もありますが。
二分探索を調べて見ましたが使いまわしできなくなりそうなのでやめました。
結局ファイルを小刻みに分割することにしました。
index付けとは言えませんが、
先に位置情報ファイルを読み込んで該当ファイルを探すといった感じです。
>>81 >>86 大変勉強になりました。ありがとうございました。
0088nobodyさん
2007/02/18(日) 04:57:02ID:???行頭についてる整数値を取得すれば1行読みの1パスで行けるんじゃない?
>if ( /^\Q$count\E/s ) {
の行、$count=10のとき行頭が"100"でもマッチするね
データ構造上無いのかも知れないけど
ちなみに小分けしたファイルのどれから読み込むのかを
要求された値から機械的に算出できるようにするという工夫もあるよ
0089nobodyさん
2007/02/18(日) 09:12:59ID:???>1行読みの1パス
ファイルが100KBを超えるたびに先頭の1行を削除していたので
$new,$oldをどうやって取得するかが問題でした。
>if ( /^\Q$count\E/s ) {
if ( ^\Q$count\t\E/s )にしました。
>機械的に算出
(ファイルを100件刻みで小分け)
my $file = './log/*.dat';
my $fle_numbe = int($start / 100) + 1; #+1は必ずtrueにする為
$file =~ /\*/$file_number/e;
とりあえずこんな感じにしました。
ファイルをまたぐ方法を考え中です。
なんとなくpipeを勉強(`・ω・´)
009065
2007/02/18(日) 17:02:29ID:qiEEvOwU>そんな事、CGIでやるべきではないと気付け。
CSV処理サービスを多数に公開する趣旨にもとづき、CGIで試作しています。
CGI以外で、多数のユーザーに処理サービスを公開する方法がありましたならば、
ご教授願います。
0091nobodyさん
2007/02/18(日) 17:24:45ID:???簡単な方法としては、
(1) HTTP response header を返す。
(2) HTTP body の先頭を返す。
ここで総処理件数を表示しても良い。
(3) 時間の掛かる処理を開始する。
(4) 1件処理毎に何らかのデータを返す。
(プログレスバーのような格好の良い物の代替として)
(5) できあがったCSVをダウンロードするためのリンクを出力。
つまり、プログレスバーの代わりに、(4) で何らかのデータを
返すだけだけどね。
垂れ流し的に「n件目、処理中」ってのが同じページに繰り返し
出ちゃったり、ちょっとかっこわるいけど。
0092nobodyさん
2007/02/18(日) 17:34:02ID:???時間の掛かる処理を開始する前に
<meta http-equiv="Refresh" content="10;URL=hoge.cgi?jobid=123">
みたいなページを返して、定期的に hoge.cgi を呼び出させる。
上記のページをクライアント側へ返したらSTDOUTとSTDERRはcloseする。
hoge.cgi は与えられたパラメータ(例示のjobid=123みたいな)でどの処理か
特定し、処理途中なら進捗具合を返す、の繰り返し。
処理完了なら、CSVダウンロードのためのリンクを返す。
で、どうだろ。
0093nobodyさん
2007/02/18(日) 17:58:06ID:???十分だろ
0094nobodyさん
2007/02/18(日) 18:05:14ID:???割り切って人間に対してはそれでも良いかもね。
しかしHTTP通信上、一定時間データが流れないと、ブラウザ側が
エラーと見なしてしまうことがあるからね。
009565
2007/02/18(日) 20:30:00ID:qiEEvOwUCGI の神のご教授、感謝です。
いままでは local 環境でのプログラミング( kernel層)ばかりだったので、
CGI は可也勝手が違います。
0096nobodyさん
2007/02/19(月) 05:29:32ID:???ちょっとだけファイル書き出しておけばよさそうに感じるけど、そういう感じって出来ないのかね。
処理してるのと別の工程でそのファイル読み出して進展状況とするみたいな感じで。
0097nobodyさん
2007/02/19(月) 07:55:57ID:vpFQD8kwできるよ。一度ユーザに画面遷移してもらうという点では>>92と同じ考え方。
実装では>>92もファイルを書き出すことになるだろうけど。
0098nobodyさん
2007/02/20(火) 02:04:21ID:???use CGI;
$q = new CGI;
foreach($q->param){
といった形のソースで、POSTされたデータをハッシュで受けたいのですが、keyにあたる部分にHTMLでいうところのID要素を与えたいと思います。
ループ内でVALUEは$_で受け取れますが、ID要素に当たる部分を取得する方法はありませんか?
0099nobodyさん
2007/02/20(火) 08:31:07ID:???http://perldoc.jp/docs/modules/CGI.pm-2.89/CGI.pod
「スクリプトの渡された全てのパラメータの名前の取り出し」から
「パラメータリストのハッシュでの取り出し」まで読もうな。
0101nobodyさん
2007/02/20(火) 10:36:15ID:???■ このスレッドは過去ログ倉庫に格納されています