トップページ⇒php
1001コメント328KB

【Perl】初心者コーナーPart10

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。02/02/24 22:18ID:zOj6Yq/3
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

1:自分はこう言う事がしたい。
2:それでこんな風にやってみたが・・・
3:それだとこんなエラーが出て上手く行かなかった。

1と3が無いと誰も答えられないよ、良い回答は良い質問から。
一緒に勉強しましょう。

参考書籍はこちら【【Perl,CGI】参考書籍 第2版 】
http://pc.2ch.net/test/read.cgi/php/988809842/
CGIの質問はこちら【CGIだけど、なんか質問ある?part5】
http://pc.2ch.net/test/read.cgi/php/1009331505/
その他の雑多な話題は、【CGIに依存しないPerlの話題一般】
http://pc.2ch.net/test/read.cgi/php/991313362/

過去ログ、その他の役立ち情報は>>2-10を見よう。
0579read02/03/15 14:17ID:???
read FILEHANDLE,SCALAR,LENGTH,OFFSET
read FILEHANDLE,SCALAR,LENGTH

Attempts to read LENGTH bytes of data into variable SCALAR
from the specified FILEHANDLE. Returns the number of bytes
actually read, 0 at end of file, or undef if there was an error.
SCALAR will be grown or shrunk to the length actually read.
If SCALAR needs growing, the new bytes will be zero bytes.
An OFFSET may be specified to place the read data into some
other place in SCALAR than the beginning. The call is actually
implemented in terms of stdio's fread(3) call. To get a true
read(2) system call, see sysread.
0580わざわざ英文かよ02/03/15 14:19ID:???
`read(FILEHANDLE,SCALAR,LENGTH,OFFSET)'
`read(FILEHANDLE,SCALAR,LENGTH)'
指定した FILEHANDLE から、 LENGTH バイトのデータを読んで SCALAR に格納する。
実際に読み込んだバイト数、またはエラーがあれば undef を返す。
SCALAR は実際に読んだバイト数に合わせてサイズが変わる。
OFFSET を指定すると、読んだデータを文字列の先頭ではなく他の場所に格納する。
これは実際には、 stdio の fread コールを用いてインプリメントしている。
本当の read システムコールを使いたければ、sysread を参照せよ。
0581nobodyさん02/03/15 14:21ID:???
>>579-580

ていうか、こういうドキュメントって、なんの役にもたたんです・・・・
実際の使用例があればすんなり理解できるのに・・・・・
0582nobodyさん02/03/15 14:22ID:???
>581
>>579-580に悪いがちょっとだけ同意。
0583アホか02/03/15 14:24ID:???
$file = "/omaeha/ahoka";
open(AHO, $file) or die;
read(AHO, $aho, -s $file);
close(AHO);
058458202/03/15 14:25ID:???
a.txt: aiueo\n
-----------------------
open(A, "a.dat");
  read(A, $Dat);
close(A);

print "$Dat\n";

とかでいいのか?
0585nobodyさん02/03/15 14:29ID:???
>>581
重要なのは最初の2行なのよ。↓これでほとんど理解できるはず。
read FILEHANDLE,SCALAR,LENGTH,OFFSET
read FILEHANDLE,SCALAR,LENGTH
0586nobodyさん02/03/15 14:30ID:???
>>585 
そんなこたないよ。
はじめたばっかしの人間、言語というもの自体になれていない人間で
それで理解できる人間なんてほとんどいない。
0587nobodyさん02/03/15 14:31ID:???
>583
使い方わかったサンクス。
でもそれを見て思うんだけど、ファイルの内容を一度変数に入れる形になってるみたいだけど、
while(<AHO>)よりもメモリ喰ったりしないの?
0588だから02/03/15 14:33ID:???
習うより慣れろって言葉がある。
仕組みを説明するより、実際に使われているソースをながめたりいじったりした方が、
どれだけ理解を深めるか。

名著と呼ばれるリファレンスブックには、必ず実例が付いている。

>>585だけで理解出来るのであれば、そのような冗長な実例が付く本は
名著どころか、悪書とされているはず。
0589nobodyさん02/03/15 14:34ID:???
いやいや,変数に入れてる時点で食うよ。
readだと,どこからどこまでを読むかが指定できる。

だから $dat = <AHO> で全部読んで $dat から抽出するよりはマシ。
0590nobodyさん02/03/15 14:35ID:???
>>583
ありがと〜〜

俺も一つ質問です。
whileで読み込むと、\nごとにわかれた配列に入れることもできるワケなんですけど、
そういう用途だったら素直にwhileつかっとけよ、っていういみなんですよね?
で、一気に読み込んで表示するんだったらreadが便利だわって意味ですね?
0591nobodyさん02/03/15 14:37ID:???
大きいファイルはreadで読まないとダメだよね。
昔、数十MBのファイルを@lines = <FILE>;で読もうと思ったら、
すごく時間がかかった。readで読んだらすぐ読めた。
0592nobodyさん02/03/15 14:38ID:???
>589
なるほど。
それじゃあ何も考えずにファイルの内容全表示するだけなら
while(<AHO>){
print;
}
でいいって事かな?
readは確かに使いどころを見極めれば便利そうだ。
ありがとう。
059358202/03/15 14:40ID:???
>591
なるほど。readは ファイルデータをスカラに入れるときの性能がいいのか。

>592
うむ。それ推奨。
おれもPOST以外ではread使ったことんなかったんでいい勉強になった。

>579-580には素直に感謝。
059458502/03/15 14:46ID:???
>>588
>習うより慣れろって言葉がある。
>仕組みを説明するより、実際に使われているソースをながめたりいじったりした方が、
>どれだけ理解を深めるか。
そのつもりで、構文が大事だよって言いたかったんだが、余計にわかりにくかったな、俺。
ごめんよ。
0595nobodyさん02/03/15 14:48ID:???
>>594
勉強になったよ。ありがと〜〜
ほかのみなさんもありがと〜〜
0596nobodyさん02/03/15 14:53ID:???
>>594
そうだったのか、誤解だったかも知れない。
俺が言いたかったのは、

read FILEHANDLE,SCALAR,LENGTH,OFFSET
read FILEHANDLE,SCALAR,LENGTH

これだけ見て、たとえば、ファイルハンドルとは何か?スカラーとは?
オフセットとは実際どんな風に用いられているのか?
とか、そういうのがイメージできるような人は、その言語の上級者だって事なんだよな。
スカラーに$が付くってことすら、このステートメント見てイメージできない人って、
かなりいると思うんだよな。
俺自身、ほかの言語に行くとそういう混乱があったりする。
そういうことが言いたかっただけだったんだよな。
0597ファイル丸ごと読み込み02/03/15 15:24ID:j7EJ72ek
全文検索エンジン Namazu のインデックス作成プログラム
mkmnz での実装例。
http://www.namazu.org/ml/namazu-dev/msg00102.html

# readfile:
#
# Reads a specified file and returns its content.
# Takes one argument which can be a file name or IO::File object.
#
sub readfile ($) {
my ($arg) = @_;

my $fh;
if (ref $arg) {
if ($arg =~ /^IO::File/) {
$fh = $arg;
} else {
warn "$arg: not an IO::File object!\n";
return "";
}
} else {
$fh = fopen_or_die($arg);
}

my $cont = "";
my $size = -s $fh;
if ($size > $MAX_SIZE) {
warn "$arg: too large!\n";
return "";
}
read $fh, $cont, $size;

return $cont;
}
0598nobodyさん02/03/15 17:15ID:???
>>597
つまりそういう場合はちゃんとサイズチェックをするべきだ、と。
0599nobodyさん02/03/15 22:55ID:Wm5JdTg+
@data=<IN>;
やるなら、
push(@data,$_) while <IN>;
だな
0600nobodyさん02/03/15 23:01ID:???
>>599
ここは「初心者コーナー」なんだからネタはネタと書こうぜ。メールアドレス欄でいいからさ。
0601nobodyさん02/03/15 23:06ID:???
>599
そ、それじゃKENTの意味無し処理と変わらんぞオイ・・・
0602nobodyさん02/03/15 23:14ID:Wm5JdTg+
>>601
@data=<IN>;
作業領域に<IN>が展開され、それを@dataにコピー

push(@data,$_) while <IN>;
$_に一行ずつコピーし、一行ずつ@dataに積んでく

意味が分からん奴は、KENT以下のDQN
0603ネタ02/03/15 23:16ID:???
undef $/;
print <IN>;

ちなみに、でかいファイル食わすとOut of Memoryでした(藁
0604nobodyさん02/03/15 23:16ID:???
>>602
で、メリットはメモリ節約?
0605nobodyさん02/03/15 23:26ID:???
>602
まわりくどいことするんだな。(藁
0606nobodyさん02/03/15 23:28ID:Wm5JdTg+
>>604
ベンチマークとればわかるよ
0607nobodyさん02/03/15 23:28ID:???
>>602
$a = 1000000;
と
for(1..1000000){ $a++; }

どっちのほうが君の好み?
0608nobodyさん02/03/15 23:29ID:Wm5JdTg+
しかし、ほんと初心者スレだな
060960102/03/15 23:29ID:???
>602 >606
ん?上だと一瞬メモリ容量が二倍になるのか?
0610nobodyさん02/03/15 23:31ID:???
>608
そうだよ。おまえみたいに上級者でも見下すヤツは正直場違い。
0611nobodyさん02/03/15 23:34ID:???
>>607は本質を理解していない。

a[0] = IN[0];
a[1] = IN[1];
・
・
・

してから

result[0] = a[0];
・
・
・

と、

result[0] = IN[0]
・
・
・

の効率を話し合っているんだよ、今。
061260002/03/15 23:36ID:???
なるほどな。確かに後者の方が速い。(し、消費メモリも少ないのだろう)
ファイルがでかくなると圧倒的とも言える差だよ。
その点は認識不足だった。コレは認めよう。


だが、普通は

while(<IN>){
# ...
}
または
read IN, $buffer, $size;

を使った方がより良いのでそのテクは何らかの事情がない限り使わないがな。
061360702/03/15 23:36ID:???
>611
ネタだ。勘弁しろ。
0614nobodyさん02/03/15 23:49ID:???
>>612
認めてくれてありがとよ。
別にテクでもなんでもないんだが・・・(while倒置しただけだ)
どちらかというと、@data=<IN>;の方がトリッキーだしな。
0615nobodyさん02/03/16 00:43ID:???
ところで eval{} のに納得がいかない。
例えば,eval{ flock(xxxx); } だと flockが実行できそうな時だけ実行するの??
エラーが返ったらやっぱりなかったことにするの??

こんなちゃらんぽらんなもんなの?
0616nobodyさん02/03/16 00:49ID:???
>>615
「この中のエラーは無かった事にしてくれ」と頼んでおきながら、何か不満ですか?

それとも$@の存在を知らないとか?

オブジェクトも受け取れるのでC++ちっくな例外処理も出来るよ。

eval{
throw MyException('Hoge!');
}
if($@){
die $@->errstr;
}
061761502/03/16 00:53ID:???
とほほによると,どうやらとりあえず「eval{};」内を実行して
エラーが返ると$@にエラーメッセージを入れて処理を続けるみたいだね。
ちゃらんぽらんだが便利なもんだな(笑

>616
その通り。$@知りませんでした。
あと「eval{};」みたいだね。
061861502/03/16 00:55ID:???
>616
2つeval{};を並べるときはそのつどundef $@;せなあかんの?
0619nobodyさん02/03/16 04:32ID:???
$@には直前のevalのエラーメッセージが入ります。

eval {flock STDIN,2};
print $@ . __LINE__;
eval {print $@ . __LINE__};
print $@ . __LINE__;
0620nobodyさん02/03/16 06:23ID:???
会員制サイト
IDとパスワードでログイン
ってのはどうすれば良いですか?
ご説明は邪魔くさいと思うので
参考になるサイトがあればお教え下さい。
0621nobodyさん02/03/16 06:25ID:???
>>620
IDとパスワード入力させてあってたら会員用のにリダイレクト。
0622nobodyさん02/03/16 06:35ID:???
>620
Perlに関係無い,Basic認証のだけど。
http://www.google.co.jp/search?q=Basic%94F%8F%D8+htaccess+%83p%83X%83%8F%81%5B%83h
062362002/03/16 06:55ID:???
>>621
回答ありがとう。

>>622
Basic認証で複数ID、複数パスって
可能なのでしょうか?
0624nobodyさん02/03/16 07:03ID:???
>>623
BASIC認証知らないなら・・・もとい、認証がなんたるかわかってないなら調べてくる・
062561502/03/16 08:20ID:???
>619
さんくす!参考になります!

>621
"認証サイト"なら .httaccess 使うとヨシ。
0626nobodyさん02/03/16 10:38ID:???
認証ついでに、perlでNTLM認証できるモジュールなんかありませんか?
0627nobodyさん02/03/16 11:26ID:???
http://search.cpan.org/search?mode=module&query=NTLM
062862602/03/16 12:44ID:???
>>627
サンクス!
てか、FAQレベルでしたね・・・(;´Д`)
062962702/03/16 13:32ID:???
自分で調べるくせをつけような. ъ( ゚ー^)
0630nobodyさん02/03/16 21:34ID:???
鯖が生きてるか死んでるかを調べるには
どんなコマンドをつかったらよいですか?
自鯖を調べるのにつかいます
てか、自鯖立てるんだったらこれぐらいできるようにならんと・・・
0631nobodyさん02/03/16 21:40ID:???
ping
063263002/03/16 22:09ID:???
>>631
それはちがいます
Perlで
0633nobodyさん02/03/16 22:17ID:???
>>630
Perl初心者コーナーで聞くからには、
もちろんPerlを使っての調べ方と仮定しますが。

Net::Pingを使いましょう。
perl-5.7.3では標準添付のようです。
ただし、MSWin32だと、Errnoの関係から使えないようです。
0634nobodyさん02/03/16 22:20ID:???
>>630=632
違うんだったら、``コマンド''という表現はいかがなものか。
0635nobodyさん02/03/16 22:31ID:???
> コマンド
つまり、こういうことだろ。
$result = `ping hoge.org`;
0636nobodyさん02/03/16 22:54ID:???
>>635
漏れもそうする。
0637nobodyさん02/03/16 22:56ID:???
>>636
でも ping だと IP reachable かどうかはわかっても
サーバが動いてるか止まってるかはわからんよ。
0638nobodyさん02/03/16 23:19ID:???
>>637
がたがた言わずにソケットでコネクション張れば良かろう。
0639nobodyさん02/03/16 23:21ID:???
>>637
取りあえずサーバの定義をはっきりしようや。
1台のマシンを指すのかサーバマシン上で走ってるネットワークデーモンを指すのか。

偉そうなことを言うのはそれからにしてくれ。
0640nobodyさん02/03/16 23:22ID:???
>>633
pingには特権が必要だから,普通`ping`
0641nobodyさん02/03/17 00:14ID:???
>>637
んなこたない。
0642nobodyさん02/03/17 00:25ID:???
>>633-640
ネタにマジレスおつかれ〜
0643nobodyさん02/03/17 00:53ID:???
厨が出てこなかったら揚げ足取りばっかか…
なんでこうなるかねぇ…
064461502/03/17 01:39ID:???
flockってwin2000で使えてるのですか?anhttpd&ActivePerlです。

eval{ flock(); };
die "errer!" if $@;

でも出力はないのですが,ロックしてないクセにそのまま真返してそうで・・・
064561502/03/17 01:51ID:???
>619
遅くなったけどありがとう。つまり偽だと空が入るんだね。納得。
0646nobodyさん02/03/17 02:17ID:???
>>644
W2kは強制ロックしかかからないって聞いたことあるけど。
ホントのとこどうなってるかは知らん。
0647nobodyさん02/03/17 03:29ID:???
>>644
排他ロックを2重にかけて、ハングするか試してみればいいのでわ?
064863602/03/17 03:35ID:???
>>637
そういうときは、さくっとsynスキャンする。(嘘)
use IO::Socket;
print "ok\n" if (new IO::Socket::INET("www.kantei.go.jp:22"));
とかする。
0649nobodyさん02/03/17 10:36ID:???
>>648
最後にackを返さなければなお良いw
0650nobodyさん02/03/17 10:37ID:???
>>647
デッドロックって奴ですか!
0651nobodyさん02/03/17 14:28ID:???
ちうか"flock()"は"プロトタイプが違うぞゴルァ"てんで必ずコケる気がするんだが。
065263002/03/17 21:54ID:???
>>648
ありがとうございました
うまくいきました
065361502/03/17 23:21ID:???
>647>650
(((((||| ゚Д゚;;;)))))ガタガタガタガタ
065464802/03/17 23:40ID:???
>>635
何を恐がっていますか?w
0655nobodyさん02/03/17 23:41ID:???
>>653
過去にデッドロックで酷い目にあったSEさんの霊でしょう。
065664802/03/17 23:44ID:???
>>653
あ〜〜〜〜、デッドロックがなにか悪いことだと思ってるのね。
意図しないでデッドロックに陥るのはもちろん問題だけど、
テストとして意図的にデッドロックさせるのは、問題ないよ。
プロセス止めれば、解除されるので安心したまい。
0657nobodyさん02/03/18 02:42ID:3JM+vmYu
perlでディレクトリ以下の全ファイル容量って
調べられますか?
もちろん対象ディレクトリ以下にディレクトリが複数あっても
底の底まで調べる・・・ど?
0658nobodyさん02/03/18 03:29ID:???
>657
できるよ。
ファイルサイズ取得とディレクトリ内ファイル一覧取得を組み合わせるとか,
適当なモジュール使うとか,他のプログラム使うとかで。
0659nobodyさん02/03/18 03:30ID:???
特定のHTMLファイルから4桁の数字だけ得れるプログラムを作ってます。
データを全部配列に入れてからforeachで回して、
4桁の数字を見つけたらその部分をsubstrで取り出す・・と考えているのですが
4桁の数字を見つける処理に手間取っています。
正規表現を上手く使って^(\d{4})$とやろうかなと思っているものの、どう使ったものか・・。

スマートな方法は何か無いものでしょうか。
0660nobodyさん02/03/18 04:00ID:???
>659
m//や//は,リストコンテキストで評価すると()内のリストを返すので,
それを利用するとこんな感じ。

while (<DATA>) {
 my @tmp = /(\d{4})/g;
 push @ary,@tmp;
}
print "@ary";
__DATA__
asdf1234as
d45ad6f54a32451234
af9842s
0661nobodyさん02/03/18 11:37ID:34CtYnSp
おはようございます。凄く初歩的だと思いますが
Perl4ですけど、
@DATA[ $FORM{'ressno'} ]の値を$oldDATAに代入したいんですが
つぎのコードは文法上間違ってますか?

$oldDATA = @DATA[ $FORM{'ressno'} ];

printしてみると@DATA[ $FORM{'ressno'} ]には文字列が入ってるんですが
$oldDATAは空っぽなんです。
本を見るとよさそうに見えるんですが・・・
ココで作業が止まっちゃってるんです。
おしえていただければありがたいのですが。
0662nobodyさん02/03/18 11:43ID:???
>660
()なんて必要ないケド...
ループ内でのmy宣言はしないほうがよいのでは?
あと、その正規表現では5桁以上にもマッチしてしまうのでは?

my @array= map{ (/(\D|\b)(\d{4})(\D|\b)/g)[$[+1] } <DATA>;
print "@array\n";
__DATA__
asdf1234as
d45ad6f54a32451234
af9842s
0663nobodyさん02/03/18 11:47ID:???
>>661
$oldDATA = $DATA[ $FORM{'ressno'} ];
じゃない?
066466102/03/18 11:59ID:???
>>663
ありがとうございます。
やってみましたけど残念ながら同じ結果でした。
0665nobodyさん02/03/18 12:09ID:???
もういちど、こんぽんのデータ値を確認しては?
066661502/03/18 12:35ID:???
>661
変数名が間違ってないかもう一度確かめて。

>662
なるほど。
ループ内でmy()はしないほうがいいのか。
ループの前に宣言するか,ループの後でundefするほうがいいのね。
0667たろう02/03/18 12:37ID:eHMudoVK
一回のリクエスト/レスポンスで
クッキーをセットして取得することってできます・・・?
無理かなあ。
それかクッキーがオンかオフが判定できる方法ってありますかねえ。
0668nobodyさん02/03/18 12:46ID:???
>661
代入のタイミングが間違ってないか確認するべきかと。

printで文字列が出るという事は、@DATA[ $FORM{'ressno'} ]には文字列が入っているんだろう。
変数名の間違いという事もないと思われる。
しかし、
$oldDATA = @DATA[ $FORM{'ressno'} ];
この書き方では、@DATA[ $FORM{'ressno'} ]を変数でなく配列として認識してしまう為、その要素でなく要素数が返される。
だから>663の書き方のほうが正しい。
しかし、間違いの書き方でも、要素数の1が$oldDATAに入らないのはおかしい。
だとしたら考えられるのは変数の代入タイミングが間違っているか、変数のスコープの範囲外で判定しようとしてるかどっちかじゃないかと思われる。
0669nobodyさん02/03/18 13:00ID:???
>661
その価値のないソースを見せてみRO!
067066302/03/18 13:18ID:???
>>664
なら、@と$の間違いじゃない(配列に何か入ってる)ということで、
$oldDATA = join(undef,@DATA[ $FORM{'ressno'} ]);
とか。
0671nobodyさん02/03/18 13:23ID:???
>670
663をやってダメなのにオマエはアフォか?
067266102/03/18 13:37ID:???
>>668
ありがとうございます。その通りでした。
変数のスコープの範囲外です。
勉強不足で申し訳有りません。

他の皆さんも、ありがとうございました。

0673nobodyさん02/03/18 14:36ID:HCOk+r4Y
色々調べましたが、わからない事があるので質問します。
どうぞよろしくお願いします。
use関数についてなのですが、よく
use lib '/mylib';
というのを目にしますが、これの第二引数'/mylib/';の意味がわかりません。
ご教授いただけないでしょうか?
それともう一つ
use I18N::Japanese;
の”::”の意味は一体なんなのでしょうか?さっぱり意味不明です。
それでは失礼します。
0674nobodyさん02/03/18 14:38ID:HCOk+r4Y
>>673
補足させていただきます。
"::"がパッケージ変数へのアクセスに使われるというのは知っているのですが
use関数で使われる事の意味がわからないのです。
0675nobodyさん02/03/18 14:48ID:???
>>673
モジュールを読み込むディレクトリに'/mylib'を追加しまっせ!
'::'はディレクトリ構造を表します
I18N/Japanese.pm
067667002/03/18 14:57ID:???
>>671
おうよ。
067767302/03/18 15:27ID:HCOk+r4Y
>>675
お答えありがとうございます!
"::"の意味がよくわかりました。一ヶ月くらい悩んでただけに感動ですw
'/mylib'は、つまりlibモジュールだけの特別な引数であるという
解釈でよろしいのでしょうか?
0678nobodyさん02/03/18 15:32ID:???
>>673
正直、駱駝本を読む事をオススメする。
067967502/03/18 16:06ID:???
>>673
useの後ろに付くlibはプラグマってやつね。
プラグマはperlの動作を変えるわけ。strictとかutf8とかあるから
自分で調べてみなさい。(プラグマは慣用的に小文字を使う。)
use lib LIST;は
BEGIN { unshift(@INC, LIST) }と同じね。
@INCにはモジュールなどを探すディレクトリが入ってるわけです。
■ このスレッドは過去ログ倉庫に格納されています