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

Perl 初心者コーナー Part21

レス数が1000を超えています。これ以上書き込みはできません。
0001nobodyさん03/03/18 18:47ID:Dujz7IUF
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。

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

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


CGIだけど、なんか質問ある? Part 9
http://pc.2ch.net/test/read.cgi/php/1041530204/
参考書籍の話題は、【Perl,CGI】参考書籍 第三版
http://pc.2ch.net/test/read.cgi/php/1030209573/
その他の雑多な話題は、【CGIに依存しないPerlの話題一般/Part2】
http://pc.2ch.net/test/read.cgi/php/1030548610/
スクリプトの改造依頼は、【 スクリプト改造工房 PART 6 】
http://pc2.2ch.net/test/read.cgi/php/1047806915/

過去ログやお勧めサイトは >>2-10
0910nobodyさん03/04/12 18:50ID:???
>>907-908
分かりやすいお答え有難う御座います!
ちゃんと理解&納得出来ました。
0911nobodyさん03/04/12 18:59ID:???
>>902
<LOG> が 0 とか "" とか返したらループから抜けちゃう。
defined でチェックすればファイル末尾に達するまで確実に真値が返る。
0912nobodyさん03/04/12 19:20ID:???
>>911
ちょっと気になったので試してみたが、while (defined(my $hoge = <FH>))
while (<FH>) どちらでも "", 0 は出力されたぞ。
0913nobodyさん03/04/12 19:40ID:???
>>912
漏れもやってみたが、0のみの行があってもループ抜けないよね。
おかしいとおもたよ。
0914nobodyさん03/04/12 19:50ID:???
というか、、、
0の行→0\n
空白の行→\n
なわけで、偽にはならんわな。
0915nobodyさん03/04/12 20:02ID:???
>>914
0とだけ書いたファイルでも同じだった。
0916はしのえみ好きー03/04/12 20:14ID:???
\x00だけのファイルはどうよ?バイナリだが。
0917nobodyさん03/04/12 20:53ID:???
>>912-916
ごめん、while <> の場合は EOF までちゃんとループしてくれるね。
while(defined($var = pop @array)) { ... } てなのが頭にあったのよ。

>>914
$/ の中身が改行とは限らない。
あんまり意味はないけど $/ = \1; で1 byte 単位とか。
0918nobodyさん03/04/12 21:38ID:???
>>904
使えない関数がある時evalするべきと聞きますが、そうすると致命的エラーは発生しないものの
当然evalされた関数は実行されないんですよね?
flockとか実行されないとかなりまずいと思うのですがどうなんでしょうか。
evalしたらあとは祈るしかないんですか?

それと使えない関数があるというのはどういうことなんでしょうか。
Perlのバージョンが古いということですか?それともサーバサイドの設定によるものなんですか?
サーバのことは全くと言っていいほど無知なのでわかりません。
だいたい全体の何割ぐらいのサーバが使えないようになっているんでしょうか。
あやしい関数は使うなということなんですかね。
0919nobodyさん03/04/12 22:20ID:???
evalの是非とは関係なく、>>918はエラー処理しない人の気がする。
0920nobodyさん03/04/12 22:25ID:???
>>918
代替となるロック処理をするのは当然。
evalはエラーを出さなくするための関数じゃないんだから。

truncateとかflockはOSに依存した関数なので、OSがその機能を実装して
いなければ使えない。
0921nobodyさん03/04/13 00:10ID:???
私も >>915 さんのように、バイナリで無理やり数字のゼロだけを含む
ファイルでやってみたのですが、やはり!? while のループの中に入って
行きました。

while ($line = <FILE>) { ...

と書いたので、読み込まれた文字ゼロ (0x30) だけが $line に代入され、
そのゼロがそのまま while の条件式の値となって、偽と判断されるはず
だと思うのですが、私は何か勘違いをしているのでしょうか。
0922はしのえみ好きー03/04/13 00:20ID:???
>>921
>バイナリで無理やり数字のゼロ
>文字ゼロ (0x30)
???
0923nobodyさん03/04/13 00:39ID:???
>>922

失礼しました。誤解を招く書き方でした。

data.txt というファイルを、0x30 という1バイトのみを持つように設定して
プログラムに読み込ませるデータファイルとしました。この 0x30 を、

>>921 の文中の「数字のゼロ」および「文字ゼロ」は、この 0x30 を指す
言葉として使いました。

●data.txt の中身
> hexdump -C data.txt
00000000 30 |0|
00000001

●プログラム
> cat test.pl
#!/usr/bin/perl

open(FILE, "<data.txt");
while ($line=<FILE>) {
print "hoge\n";
}
close(FILE);

●実行の様子
> ./test.pl
hoge
0924はしのえみ好きー03/04/13 00:54ID:???
>>923
それは全然意味ないんじゃないのか?普通に0と書くのと変わらないじゃん。
ってことで\x0でやってみた。

$ perl -e 'open(F,">data.txt");print F "\x00";close(F);'
$ dump data.txt
data.txt:

Addr 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 2 4 6 8 A C E
-------- ---- ---- ---- ---- ---- ---- ---- ---- ----------------
00000000 00 .

$ perl hoge.pl
hoge

入ってる。
0925はしのえみ好きー03/04/13 00:55ID:???
>>921
おっと、説明不足だったが、
>バイナリで無理やり数字のゼロ
の意味が分からないってことだよ。
0x30を書くんだったら普通にテキストエディタで"0"って書けばいいんじゃん。
0926nobodyさん03/04/13 01:13ID:???
>>921
どうやら while の条件部は行入力演算子を使った場合に限って、
真偽値ではなく defined か否かで判定されるみたいだね。
行入力演算子が undef 返すのは EOF に達した時だけだから、
ファイルは全部読まれるみたい。

統一感の無さは Perl らしいけど、便利と言えば便利。
0927nobodyさん03/04/13 01:15ID:???
凄く間抜な質問だと思いますが、あえて聞いてください
\0x00とかのコードはどう知ればいいんでしょうか。
どこか一覧表とかあるのかな…。
あと、ずっと気になっていた、画像を生成する際の数字の配列は
みなさんどうやって計算?しているのでしょうか。
0928nobodyさん03/04/13 01:18ID:???
画像を生成する数字って何?
0929nobodyさん03/04/13 01:23ID:???
>928
ダミー画像などでよく見かける、テキストだけで生成してるやつです。
別に、画像を読み込んで出力すれば良いんだけど
どうやるのか気になってたもので。
0930nobodyさん03/04/13 01:48ID:???
お絵かきソフトで作って バイナリエディタで覗いてみたら?
色数落としていくとそれになるよ。
0931nobodyさん03/04/13 02:07ID:???
なるほど、ありがとうー
早速明日試してみる事にします。
今日は眠いのでもう寝ます…。
0932はしのえみ好きー03/04/13 02:18ID:???
>>927
>\0x00とかのコードはどう知ればいいんでしょうか。
>どこか一覧表とかあるのかな…。
http://www.psl.ne.jp/perl/pdojo00b.html
0933nobodyさん03/04/13 08:46ID:P9fP4Q1N
http://www.sexy-rush.com/sukebe/bbs8/img/img20030330223714.jpg
0934nobodyさん03/04/13 14:30ID:???
結局 >>926 からすると、
>>890 の
while (defined(my $article = <LOG>)) {...
の書き方は助長なのか?
0935nobodyさん03/04/13 14:45ID:???
>>934
冗長ですな。
でも、私も厳密に考えたら defined を使って書いていたと思う。

>>926 の

「どうやら while の条件部は行入力演算子を使った場合に限って、
真偽値ではなく defined か否かで判定されるみたいだね。 」

というのはわかったのだけど、なんとなく釈然としない。
マニュアルのどの部分に、そのことが書いてあるんだろう・・・。
0936nobodyさん03/04/13 14:55ID:???
http://www.perldoc.com/perl5.6/pod/perlop.html#I-O-Operators
0937nobodyさん03/04/13 15:00ID:???
>>935
「どうやら while の条件部は行入力演算子を使った場合に限って、
真偽値ではなく defined か否かで判定されるみたいだね。 」
は違うみたい。
The defined test avoids problems where line has a string value that would be treated as false by Perl,
for example a "" or a "0" with no trailing newline. If you really mean for such values to terminate the loop, they should be tested for explicitly:

while (($_ = <STDIN>) ne '0') { ... }
0938nobodyさん03/04/13 16:39ID:???
while (my $line = <STDIN>) { print $line }

In these loop constructs, the assigned value (whether assignment is automatic or explicit)
is then tested to see whether it is defined.
The defined test avoids problems
where line has a string value that would be treated as false by Perl,
for example a "" or a "0" with no trailing newline.
If you really mean for such values to terminate the loop,
they should be tested for explicitly:

while (($_ = <STDIN>) ne '0') { ... }
while (<STDIN>) { last unless $_; ... }
0939nobodyさん03/04/13 16:40ID:???
↓↓↓↓↓↓↓↓↓↓  いい加減な訳  ↓↓↓↓↓↓↓↓↓↓↓

while (my $line = <STDIN>) { print $line }

これらのループ構造では、(自動的であれ、明示的であれ)指定された値は
defined されてるか否かテストされます。definedされてるか否かのテストをすると、
次の行を伴わない "", "0" のような、Perlでは 偽 として扱われる文字列が
行中にあったときの問題を避けることができます。
もし、おまいが本当にそれらの値("", "0")でループを終了させるのなら、
明示的に次のようにしる:

while (($_ = <STDIN>) ne '0') { ... }
while (<STDIN>) { last unless $_; ... }

↑↑↑↑↑↑↑  いい加減な訳、ここまで  ↑↑↑↑↑↑↑↑↑

ということは、
「どうやら while の条件部は行入力演算子を使った場合に限って、
真偽値ではなく defined か否かで判定されるみたいだね。 」
は正しいのか?間違ってるのか?

誰か正確に訳してください。
094092603/04/13 17:45ID:???
#--- test.p ---
my $file = './test.txt';
open F, '>' . $file or die;
print F '0';
close F;
open F, '<' . $file or die;
A: { print 'A' while <F>; seek F, 0, 0 }
B: { my $foo; print 'B' while $foo = <F>; seek F, 0, 0 }
C: { my($foo, $bar); print 'C' while $foo = $bar = <F>; seek F, 0, 0 }
D: { my($foo, $bar); print 'D' while defined($foo = $bar = <F>); seek F, 0, 0 }
E: { print 'E' while <F> eq '0'; seek F, 0, 0 }
print "\n";
__END__

> perl test.p
ABDE

B が特別扱いっぽく見えるけど、「while の条件部に行入力演算子
のみを置いた場合はデフォルトで $_ に代入」との兼ね合いだろうね。
つまり while <> は while $_ = <> の文法的略記でしかなく、内部的
には後者で処理されてるんじゃないかな。

だから >>926 を厳密に言うと、「while の条件部は $var = <> ならば
defined か否かで判断、そうでない場合は真偽値で判断」だね。
ドキュメント読んでないけど、挙動を見る限りは。
0941nobodyさん03/04/13 22:40ID:???
#!/usr/bin/perl

$logfile = "./accesslog.dat";
$agent2 = $agent = $ENV{'HTTP_USER_AGENT'};

if ($agent =~ /AOL/) { $agent = 'AOL'; }
略・・・
elsif ($agent =~ /PDXGW/i) { $agent = $os = 'H"'; }

if ($agent2 =~ /win[dows ]*95/i) { $os = 'Windows 95'; }
略・・・
elsif ($agent2 =~ /X11/ || $agent2 =~ /SunOS/i || $agent2 =~ /Linux/i
|| $agent2 =~ /HP-UX/i || $agent2 =~ /FreeBSD/i || $agent2 =~ /NetBSD/i
|| $agent2 =~ /OSF1/i || $agent2 =~ /IRIX/i) { $os = 'UNIX'; }

$referer2 = $ENV{'HTTP_REFERER'}
if ($referer2 =~/\w/){$referer = "$referer2";}

open(FILE, ">> $logfile");
flock(FILE,2);
print(FILE "$ENV{'DATE_LOCAL'},$referer,$agent,$os,$ENV{'REMOTE_HOST'}$ENV{'REMOTE_ADDR'}\n\n");
lock(FILE,8);
close(FILE);
exit;

これが動かないのでチェックにかけると、
if ($referer2 =~/\w/){$referer = "$referer2";}
の;}の近くがおかしいとでました。サッパリわかりません。
ちなみに、ここのリファラーのif文を省いたときは正常に実行できました。
0942nobodyさん03/04/13 22:42ID:???
agentのif文も、KENTさんのスクリプトをコピペすると正常なのに、
自分で同じものを書くと、;}の近くがおかしいとでます。
さらに、コピペではelsifはひっかからなかったのに、自分で書くと、
elsifというのはおかしいとか注意されます。もうサッパリです。
0943nobodyさん03/04/13 22:44ID:???
訂正しておきます。
$referer2 = $ENV{'HTTP_REFERER'}
if ($referer2 =~/\w/){$referer = "$referer2";}
else{$referer = 'Direct Access';}
です。
0944nobodyさん03/04/13 22:44ID:???
>>942
嘘つき。同じもの書いたら同じ動作になるに決まってんだろ
0945nobodyさん03/04/13 22:47ID:???
>>944
そうなんですけど、自分で書くと、;}のところや、elsifがひっかかります。
チャックプログラムもKENTさんのところのやつです。
なんでですか?秀丸を使ってるんですけど、なにか関係ありますか?
0946nobodyさん03/04/13 22:50ID:???
$referer2 = $ENV{'HTTP_REFERER'} ←ここにセミコロンが無いのは気のせいか?
ほんとに同じ物を書いたのか?
0947nobodyさん03/04/13 22:54ID:???
>>946
あ、ほんとだ。できました。ありがとうございます。
どうやら=文書くときにセミコロンを忘れる癖がついていたようで前にもこのようなことがなったんですね。。。
スレ汚しすいませんでした。
0948nobodyさん03/04/13 23:18ID:pEN/2OPI
以前この板で管理人のひろゆき氏よりもエラそうな一言
このスレに2度とくるな!
と書かれた者ですが質問しても良いですか?
0949nobodyさん03/04/13 23:19ID:???
>>948
もしここで私が「ダメだ」と言ったら
ひろゆきさんに問い合わせるつもりですか?
それともいちいち2ch系サイトに
「あなたのサイトをひろゆきさんにチクリます」
とメールを出したり書き込んだりするつもりですか?
0950nobodyさん03/04/13 23:21ID:???
2度と来るなと言われたってことはかなりうざい香具師なんだろ?質問はしないでくれ。
0951nobodyさん03/04/13 23:23ID:???
2ちゃんで叩かれるのはそれなりの理由がある事が多い。
>ひろゆき氏よりもエラそうな一言
などと反省の色が見えないことを考えると二度と書き込まないほうがよかれ。
0952nobodyさん03/04/13 23:27ID:???
庭の石をひっくり返したら、
だんご虫が群がってるよね。
あれみたい・・・。 このスレ。
0953nobodyさん03/04/13 23:29ID:???
>>952=>>948 書き込むなっつってんだろ?
0954nobodyさん03/04/13 23:30ID:???
949=950=951=952
自演
0955nobodyさん03/04/13 23:41ID:pEN/2OPI
>>953
953番さんここの管理人ですか?
0956nobodyさん03/04/13 23:41ID:???
結城さんのところに、
「<tt>while (defined($line = <FILE>)) { ... }</tt> でdefinedがない場合、ファイル末にある改行なしの"0"が正しく取得できるかどうかの調査。
」
というのがありました。
http://www.hyuki.com/pb/pbmldig.html
0957nobodyさん03/04/13 23:54ID:???
>>955
そう思うのなら書けば良かれ。
095893703/04/13 23:54ID:???
>>955=>>952=>>948
もういいよ。うざいバカだな。

>>956
なるほど。新しい版になると回避するようになってるってことか。
しかし MacJPerl 5.2.0r4 はわけわからんな。何が影響してるんだろうか。
やっぱ>>937-938の通りだな。心配だったらチェックしろってことか。
まあ俺の周りでは5.6以降しかないから大丈夫だろうな。
情報ありが�d
095994803/04/13 23:56ID:???
952は流れを変えようとしているけど違いますよ。
955はもろそうですけど。
0960nobodyさん03/04/13 23:59ID:???
次スレまだ?
>>948
質問があればしろよ。
096194803/04/14 00:10ID:???
なんか、荒らしちゃったみたいなので又にします。
失礼しました。
0962nobodyさん03/04/14 01:18ID:oETCFM9h
例えば55555555という数字があってそれを55.5Mというようにするにはどうしたらいいんでしょうか?
0963nobodyさん03/04/14 01:22ID:???
55555555という文字列から、テキトーに3文字持ってきて、ならべる。
最後の文字の直前に、ピリオドを突っ込む。

以下独り言。

バイト数をメガバイトや、キロバイトという単位で表示したいのなら、
1024で割れば、キロバイトになる。
さらに1024で割ればメガバイトになる。

コンピュータの世界の数字ではないのなら、1024の代わりに1000を使う。
0964nobodyさん03/04/14 01:36ID:???
>>963
どうもありがとうござます。
数字÷1024÷1024をなんで浮かばなかったんだろう・・
0965nobodyさん03/04/14 02:30ID:???
>>937
948がうざがられたらどうするんだ!?
お前責任取れよ!
>>964
さらに1024で割ってギガバイト
0966nobodyさん03/04/14 03:13ID:???
>>965
馬鹿なことはせずに落ち着けよ。
0967nobodyさん03/04/14 04:08ID:???
${"domo"} = "ども";
use strictだと怒られてしまいます。
何故でしょうか…。
0968はしのえみ好きー03/04/14 05:13ID:???
変数名は何?
0969nobodyさん03/04/14 05:44ID:???
>>967

use strict;

と書くと、

use strict 'refs';

と、書いてあるときと同じ制限(シンボリックリファレンスの禁止)が効いてくるからじゃないかな。
0970はしのえみ好きー03/04/14 06:28ID:???
うわっ恥ずかしー。てっきりハッシュかと思ってた(鬱氏
0971nobodyさん03/04/14 09:30ID:???
存在するかどうか不明なのですが...

処理を行う文字列内に2バイト文字が含まれている場合、処理を中断させたいのですが
Perl でコレに適した関数が存在しますでしょうか?

関数が存在しない場合、この様な処理を行いたい場合どのような考え方を行えばよいでしょうか?
0972nobodyさん03/04/14 10:03ID:???
EUC_JP なら、2バイト文字のどっちのバイトもトップビットが立ってるです。
0973nobodyさん03/04/14 10:57ID:???
>>972様
それを利用して正規表現でマッチングすれば実現できそうですね!
因みに、コード S-JIS の場合は同じ様な方法で処理可能でしょうか?
0974nobodyさん03/04/14 12:44ID:???
>>973

http://tohoho.wakusei.ne.jp/wwwkanji.htm
まず、ここ↑だけでなく、とほほさんのページWWW入門を端から端までざっと読まれたし。

あと、「2バイト文字」 「判定」 とかでぐぐられたし。
0975nobodyさん03/04/14 13:21ID:???
>>974様
うお!
杜甫々様にこんな項目があったなんて...
こちらの項目内をじっくり調べて見る事にします!

感謝です ^^
0976nobodyさん03/04/14 14:53ID:???
my $hoge='aaa' if($hoge);
と書くと変数が空になる場合とそのまま表示される場合があるのはなぜですか?
0977nobodyさん03/04/14 15:06ID:???
冷やすことしか思い浮かばずに人を簡単に邪魔者にする、
言いたい事だけだを言って逃げるような人間は必要ない。
0978nobodyさん03/04/14 15:15ID:???
>>976
どういう処理を期待している?
0979nobodyさん03/04/14 15:19ID:???
直前の質問に回答もせず(できず)に
言いたい事だけだを言って逃げるような人間は必要ない。
0980nobodyさん03/04/14 16:40ID:???
煽りデビューしてまだ間もないのかな
098125103/04/14 16:42ID:???
>>976
どう動くかわかった物じゃないな・・・
0982nobodyさん03/04/14 23:20ID:Fu0phwZ6
zisure
0983nobodyさん03/04/14 23:30ID:???
オイ糞ども
答えられねーくせに常駐してんなよ
0984nobodyさん03/04/14 23:32ID:???
>>983
すまんがあんた誰?
0985nobodyさん03/04/15 00:06ID:???
>>984
俺だよ俺。
0986はしのえみ好きー03/04/15 00:34ID:???
>>985
ああ、君か。
0987nobodyさん03/04/15 01:11ID:GCPlWzzF
今携帯なんですが、ついさっきPCでアップした環境変数をすべて生で表示するCGIを設置したんですが動きません。
http://f9.aaacafe.ne.jp/~raiha/printenv.cgi
誰かこれと同じようなCGIをくんで、どこかにUPしてもらえないでしょうか?
本っ当にすいません、携帯なんで。。。
0988はしのえみ好きー03/04/15 01:13ID:???
>>987
実行権がついてないよ。多分。
0989nobodyさん03/04/15 01:22ID:iui3dkW8
自分で書いたCGIの場合自分でパーミッションは考えるんですよね?
あと、この場合のパーミッションはどうしたらよいか教えて下さい。

もしよろしければ、UPしてもらいたいんですが。。。だめですか?
0990はしのえみ好きー03/04/15 01:35ID:???
>>989
別にコードに書くわけじゃないよ。http://fh.aaacafe.ne.jp/ ここで聞いて来い。と思ったがろくな説明書いてないな。
ftpでUpしてるならchmodしろ。FTPクライアントによってやり方は違うからそれに関しての質問はスレ違い。
0991はしのえみ好きー03/04/15 01:35ID:???
誤:FTPクライアントによってやり方は違うからそれに関しての質問はスレ違い。
正:FTPクライアントによってやり方は違うが、それに関しての質問はスレ違い。
0992nobodyさん03/04/15 03:05ID:???
$a = 10;
$b = 3;
$c = $a / $b;
だと $c = 3.3333〜になってしまいますし
int($a / $b) だと $c = 3になってしまいます
少数第2位でそろえるためにはどうすればいいんでしょうか?
一応
$c = (int($a * 100)/$b)/100; っていうのも考えて見たんですが
もっとスマートにやる方法ないでしょうか
表示するわけではないのでprintf()は使えません。
0993nobodyさん03/04/15 03:09ID:???
>>976
どんな意図があるか分かりませんが、
せめて
use strict;
してください。
0994nobodyさん03/04/15 03:12ID:???
>>992
そんなあなたに sprintf
0995nobodyさん03/04/15 03:14ID:???
>>994
サンクス 助かったYO。
sprintfでフォーマット決めて変数に代入できるんだね。
0996nobodyさん03/04/15 07:22ID:HrV7+0uT
じすれは?
0997nobodyさん03/04/15 10:14ID:???
ああ、次が立ってなかったんだな
じゃあ、立ててくるから待ってて
0998nobodyさん03/04/15 10:17ID:???
次スレ

Perl 初心者コーナー Part22
http://pc2.2ch.net/test/read.cgi/php/1050369328/l50
0999nobodyさん03/04/15 13:57ID:???
} # http://pc2.2ch.net/test/read.cgi/php/1047980851/
1000nobodyさん03/04/15 13:58ID:???
__END__
10011001Over 1000Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。