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

Perlコーディング初心者質問スレ Part 49

レス数が950を超えています。1000を超えると書き込みができなくなります。
0001nobodyさん2006/05/31(水) 04:32:28ID:???
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

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

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0873nobodyさんNGNG
クリップボードの末尾はNULLで判断されるから
08748722006/06/23(金) 22:58:10ID:HrkNw3LR
>>873
なるほど。
それではどうすればいいのでしょうか?
手書きで移すしかないのでしょうか。
0875nobodyさん2006/06/23(金) 23:16:19ID:???
画像ファイルとして保存しておいて読み込めばいいじゃない。
ソースにバイナリを埋め込もうとするなよ、と。
0876nobodyさん2006/06/24(土) 00:26:02ID:???
すいません質問があるんですが

「 $hoge /= $fuga; 」

で、$hugaの値は始め「0」なのですが、この場合どうすればよろしいでしょうか?
割る数が0だとエラーですよね・・・・
0877nobodyさん2006/06/24(土) 00:32:56ID:???
$hoge /= $fuga unless $fuga == 0;
0878nobodyさん2006/06/24(土) 00:34:07ID:???
>>876
経験からすると、そういう時はだいたい計算方法自体が間違ってる。ループの開始値は実は1とか。
まあこれで正しい計算ができると言うのなら $hoge /= $fuga || 1 とか。
08798762006/06/24(土) 01:54:46ID:???
>>877-878
ありがとうございます。

一応いろいろいじっていて、「$hogehoge = eval { $hoge / $fuga; };
と、形が崩れてしまったのですがこれで動きました・・・が、これでも問題ないでしょうか?
0880nobodyさん2006/06/24(土) 02:02:12ID:???
>>879
$fugaが0のとき、$hogehogeの値は何になって欲しいの?
08818762006/06/24(土) 02:06:23ID:???
>>880
一応「0」が入って欲しいと思っています。
08828762006/06/24(土) 02:10:30ID:???
あぁ、すいません・・・・
素直に>>877さんのを使わせていただきます。うまくいきました。

ありがとうございます。
0883nobodyさん2006/06/24(土) 02:17:12ID:???
>>881
0で割ったら0にならないものを、無理やり0にしようとしてるんだから
素直に場合わけした方がいいよ。
if ($fuga == 0) {
$hogehoge = 0;
} else {
$hogehoge = $hoge / $fuga;
}
eval使うと遅いし。
$ perl
use Benchmark;
timethese(1_000_000,
{'ore'=>sub{if ($fuga == 0) {$hogehoge = 0;} else {$hogehoge = $hoge / $fuga;}},
'omae'=>sub{$hogehoge = eval { $hoge / $fuga };}});

Benchmark: timing 1000000 iterations of omae, ore...
omae: 6 wallclock secs ( 6.64 usr + 0.00 sys = 6.64 CPU) @ 150625.09/s (n=1000000)
ore: 0 wallclock secs ( 0.39 usr + 0.00 sys = 0.39 CPU) @ 2557544.76/s (n=1000000)
(warning: too few iterations for a reliable count)
08848762006/06/24(土) 02:18:28ID:???
>>883
あ、はい。
こんな夜遅くにありがとうございます。
0885nobodyさん2006/06/24(土) 02:48:48ID:LjIFBTan
自分が借りてる鯖では「flock関数」が使えるんですが
その場合ためらいも無く「flock(LOG,2);」とかやっても問題無いですか?
0886nobodyさん2006/06/24(土) 04:03:57ID:???
>>885
flockが使えないような鯖で動かす予定がないなら良いんじゃない?
漏れは、もう長いことflockのためにeval使ったことなんて無いな…
# っつか、flock非対応の環境に出会ったことが無いんで、
# 対応してない環境では致命的なエラーになる事をすっかり忘れてた。
08878722006/06/24(土) 17:30:41ID:1EkY/rQf
>>875
それじゃあ画像をいじるCGIを作るのが難しいですよ。
どこの何番が何に当たるとか、逐一みたいですし。

あ、勘違いしてるかもしれません。
ASCIIコードで埋め込みたいんです。
バイナリで埋め込むという表現は間違いでした。すみません。
0888nobodyさんNGNG
$binary = "\x00\x01\x02\x03\x04";

とか、packとか
08898722006/06/24(土) 17:52:23ID:1EkY/rQf
>>888
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52


こういう感じです。
件のものですが、locationと同じですよね。
まあ

print "location:/img/logo.gif;\n\n";

でやってもエラーが出てしまって困ってるのですが。。。。
なんかスランプです。あつくtえ
0890nobodyさん2006/06/24(土) 18:06:51ID:???
どうでもいいけど、>>872が何をやりたいのかさっぱり分からない。
0891nobodyさん2006/06/24(土) 18:18:08ID:???
Locationはhttp://から
0892nobodyさん2006/06/24(土) 19:40:28ID:???
Spreadsheet::ParseExcelについての質問です。

英語で記載したセルとハイパーリンクだけは抽出してくれるのですが、日本語部分が文字化けしてしまいます。
モジュール部分には、以下のように記載しています。

use Spreadsheet::ParseExcel;
use Spreadsheet::ParseExcel::FmtJapan;
use Unicode::String;

Googleなどの検索では、これで上手く言っている人が大部分でした。お判りになる方がいたら、教えてください。
08938722006/06/24(土) 21:10:03ID:1EkY/rQf
とりあえず以下で件の読み込んでやるというのをやってみました。

print "Content-type: image/gif\n\n";
open FH,"../img/logo.gif";
my @img = <FH>;
pack "h", @img;
print @img;
close;

そうしたら正常でない画像が表示されました。多分変換部分が間違いなんですね。
hじゃなかったのかな。

>>890
すみません。暑さに参っておりました。35度って凄いですね。
冷房使えない体なので。

フォトショップみたいなCGIを作ろうと思ってます。
ご覧の通り未熟ですので今年一杯の趣味感覚で取り組んでいます。

>>891
ありがとうございましたm(__)m
やさしさを感じましたm(__)m
08948722006/06/24(土) 21:12:18ID:1EkY/rQf
>>892
文字コード問題では?
モジュールに渡す時に決められた文字コードにしておかないといけないとかはないのですか?
その他もジーコ度全般を見直してみhてあ。
0895nobodyさん2006/06/24(土) 21:23:27ID:???
>>894
ありがとうございます。
とりあえず、そこから調べてみることにします。
0896nobodyさん2006/06/24(土) 22:54:50ID:???
>>893
おそらくbinmodeでrawにすればおk
さもないと改行コードが自動的に変換されたりしてしまうので。
0897nobodyさん2006/06/25(日) 00:04:20ID:???
ログから特定の行数だけ抜き出す時は、どうしたらいいんでしょうか。
掲示板ログから出力すると、行数が多いので、
件名だけか、本文の何行まで抜き出すという風に出来たらと思うんですけど。

@match = map { $_->[0] }
sort { $b->[18] <=> $a->[18] }
map { [$_, split /\|\|\|/] }
@match;
my$i = 5;
foreach $line (@match) {
@mdata = split(/\|\|\|/,$line);
if ($i > 0) {
print "<CENTER>\n";
&table_html($HoD);
&subj_date_name_hp_html ("main", \@mdata, $HoD);
0898nobodyさん2006/06/25(日) 00:14:20ID:???
エスパーかもーん
08998722006/06/25(日) 00:28:43ID:CLTK8aRM
>>896
binmodeで、rawにやってみます。ありがとうございます。
>>897
決めたバイトだけ読み取るとか・・・・というかどういう形式で保存されてるのかさえ
わかりやすく説明したらきっと詳しい人がズバリで教えてくれると思いますよ。
0900nobodyさん2006/06/25(日) 01:37:46ID:???
>897
spliceで削除しちゃえばいいんじゃないのか?
09018972006/06/25(日) 03:45:53ID:???
>>899
ありがとうございます。
バイトで読み取りをしてみたのですが、うまくいかず…。
もっと勉強します…。
spliceでいけました。

>>900
spliceでいけました。
ヒントありがとうございます。
本当に本当に助かりました!
ありがとうございました。
0902nobodyさん2006/06/25(日) 06:35:30ID:???
>>893
img/logo.gifが純正のgifファイルなら、
何も変換せずにprint <FH>で表示できる。
windows環境ならbinmodeが必要。

binaryが見たいなら、とりあえず
print unpack"H*",join"",<FH>で見れる

各要素を配列として得たいなら
my@a=unpack"C*",join"",<FH>など、・・・
0903nobodyさん2006/06/25(日) 07:42:22ID:???
>^)+++< (^_^#) (*^(^ *) [^<>^]
0904nobodyさん2006/06/25(日) 10:22:03ID:???
>>893 の 「フォトショップみたいなCGI」 ってのがすごく気になる・・・
フォトショップの何をしたいのかさっぱりわからんw 全体だったらかなり無謀だよね。
0905nobodyさん2006/06/25(日) 12:03:42ID:???
>>904
Photoshop を Web アプリとして再実装できたら面白いと思ふ。
例えば中小規模でのグラフィックワークステーション共有とか、コスト面でのメリットが出るならいけそうじゃないか?
0906nobodyさん2006/06/25(日) 12:06:28ID:???
0;
09078722006/06/25(日) 12:47:39ID:CLTK8aRM
print "Content-type: image/gif\n\n";
open FH,"../img/logo.gif";
binmode FH;
my @img = <FH>;
pack "raw", @img;
print @img;
close;

これだと画像部分が×になって表示されません。でも画像のサイズはあってます。

print "Content-type: image/gif\n\n";
open FH,"../img/logo.gif";
binmode FH;
print <FH>;
close;

だとやっぱりぐにゃぐにゃの画像になって表示されてしまいます。

winXP
apache1.3.3
active perl 6.8
です。
0908nobodyさん2006/06/25(日) 13:10:04ID:???
binmode STDOUT;

もお忘れなく
09098722006/06/25(日) 13:22:05ID:CLTK8aRM
>>908

print "Content-type: image/gif\n\n";
open FH,"../img/logo.gif";
binmode STDOUT;
print <FH>;
close;

ありがとうございました。これでできました。
binmode FH;はファイルをバイナリレベルでいじる時で、出力をバイナリにするには
binmode STDOUT;が必須だったのですね。

ありがとうございました。

>>904-905
専用サーバを借りてるので、時間掛けながらゆっくりやろうとかと思います。
どこらへんまで出来るのかは現時点の私ではわかりませんので、みなさんからすると
アホなことかもしれません。でも面白そうなので。
0910nobodyさん2006/06/25(日) 13:44:45ID:???
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)

こういうアクセスログファイルがあって、
open FD,"access.log";
while (<FD>){
print $_,"<br>\n";
}

とするとブラウザのところで何行にもなってしまいます。
つまりwhileが行末の改行以外でちょんぎってはじめてしまってるのです。
一応
open FD,"access.log";
my @line = <FD>;
close FD;
print $line[0];
も試してちゃんと行ごとの配列になってましたので、whileの影響だとは思うのですが。
0911nobodyさん2006/06/25(日) 13:46:56ID:???
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)

こういうアクセスログファイルがあって、
open FD,"access.log";
while (<FD>){
print $_,"<br>\n";
}

とするとブラウザのところで何行にもなってしまいます。
つまりwhileが行末の改行以外でちょんぎってはじめてしまってるのです。
一応
open FD,"access.log";
my @line = <FD>;
close FD;
print $line[0];
も試してちゃんと行ごとの配列になってましたので、whileの影響だとは思うのですが。
多分<FD>これでちゃんと行ごとに渡そうとしてるにもかかわらずその中の何かのコードに
whileが反応して行の途中で区切って処理を開始してしまうんだと思います。

whileに行ごとにやらせたいのですが、何かwhileのモードを変える方法でもあるのでしょうか?
0912nobodyさん2006/06/25(日) 14:09:12ID:???
ImageMagickがインストールされてないサーバで、インストールする権限もない状態で、
なんとか使うことは出来ないのでしょうか?
0913nobodyさん2006/06/25(日) 16:30:20ID:???
>>912
鯖缶にお願いメールを送信する
0914nobodyさん2006/06/25(日) 16:38:32ID:???
>>911
何言ってんの?

while (<FD>){
print $_;
}

こうすれば行ごとになるんでしょ? それに加えて \n 入れたら2行になるの当たり前じゃん。
09159152006/06/25(日) 16:58:59ID:???
$rand = int(rand(6));

if($old_rand == $rand)
{ $rand = $rand + 1; }
if($rand == 0)
{ $key = "000"; $old_rand = $rand;}
elsif($rand == 1)
{ $key = "001"; $old_rand = $rand; }
elsif($rand == 2)
{ $key = "002"; $old_rand = $rand; }
elsif($rand == 3)
{$key = "003"; $old_rand = $rand; }
elsif($rand == 4)
{ $key = "004"; $old_rand = $rand; }
else
{ $key = "006"; $old_rand = $rand; }
上記の部分を処理が来るごとに使っています。
前回と同じ値の場合は+1して2度連続で同じkeyにならないようにしているのですが
何故か同じkey(例:$key = 002等が)が重なることがあります。
前回と同じ数値の場合は+1しているので重なることはないと思うのですが
なぜ同じ数値が出るのでしょうか?
どこか間違っている場所があればアドバイスいただければと思います。
0916nobodyさんNGNG
よくわかんないけど、
+=とsprintf使った方がよさげ
0917nobodyさん2006/06/25(日) 17:13:02ID:???
$rand = int(rand(6));

$rand += 1 if ($old_rand == $rand);
if ($rand < 5) {
 $key = sprintf("%03d", $rand);
} else {
 $key = "006";
}
$old_rand = $rand;

006は重なるだろうけど、他の部分で$old_rand変更しちゃってるとか。
09189152006/06/25(日) 17:21:20ID:???
レスありがとうございます。
もしかして
{}内で$old_randに入れても{}内だけで有効で
{}外では$old_randって何も入ってない状態になりますか?
もしそうなら私のバカなミスということになりますが・・・。
0919nobodyさん2006/06/25(日) 17:23:14ID:???
いや、そんな事は無い。
同じ処理が全部の条件に入っていたから括り出しただけ
0920 ◆TWARamEjuA NGNG
(´-`).。oO(前回と同じ数字が出るのも乱数(疑似乱数)だと思うけれども、、、)
0921nobodyさん2006/06/25(日) 18:51:53ID:???
>>915
こんなコード書いてみた。いろいろ弄って考えてみて。

foreach(1..1000){
r();
}
exit;

BEGIN{
my ($old_rand, $old_key) = (0, 0);
sub r
{
my $rand = int(rand(6));
$rand++ if($old_rand == $rand);

my $key = sprintf("%03d", ($rand < 5 ? $rand : 6));

print "OUT! key:$old_key,$key rand:$old_rand,$rand\n" if ($old_key eq $key);
$old_rand = $rand;
$old_key = $key;

return $key;
}
}

# 本当は、元のままのコードを使いたかったのだけれど、
# プログラム関連の板で改行制限が厳しいとはどういうこった!>ひろゆき
0922nobodyさん2006/06/25(日) 19:09:56ID:???
なぜBEGINブロックなのか不明
0923nobodyさん2006/06/25(日) 19:17:36ID:???
>>922
初期化してるから。
0924nobodyさん2006/06/25(日) 21:05:56ID:???
>>920
だから前回と同じ乱数字が出たら+1してるんじゃない?
09259112006/06/25(日) 21:28:57ID:???
>>914
my %access;
# どのページにアクセスしてきたか
$access{p} = ( p => "index" );
# アクセス人物のIPアドレス
$access{ip} = $ENV{'REMOTE_ADDR'};
# アクセス時刻の記録
$access{time} = sprintf "%04s%02s%02s%02s%02s%02s",sub{shift()+1900,shift()+1,@_}->(@{[gmtime(time+32400)]}[5,4,3,2,1,0]);
# アクセス人物のブラウザ
$access{browser} = $ENV{'HTTP_USER_AGENT'};
# 書込み処理
open FH,"+>access.log";
flock FH,2;
my @line = <FH>;
my @new_line = join ",",@access{qw/p ip time browser/};
for ( my $i=0; $i<@line; $i++ ){
my @temp = split /,/,@line;
if ( $access{ip} ne $temp[1] and 1000000000 > $access{time} - $temp[2] ){
push (@new_line,join (",",@temp));
}
}
for ( my $i=0; $i<@new_line; $i++ ){ print $new_line[$i],"\n" }
while ( <@new_line> ){ print FH $_,"\n" }
close FH;

これを実行するとブラウザには一行で表示されますが、ファイルにはブラウザの種類部分が
何行にもわたって書き込まれてます。

ファイルに書込みするのもforでやれば問題は解消します。
なぜでしょうか?
0926nobodyさん2006/06/25(日) 21:52:14ID:???
よくそんなに分かりにくく書くなぁ
配列を<>に入れてるのも初めて見たわ。
0927nobodyさん2006/06/25(日) 22:03:36ID:???
質問に無関係なところを除去しようとするのは良い心がけだが、動作チェックくらいしよう、な?
+>で開いて読み込めるわけないし。+<の間違いだとしてもtruncateしてないし。
split /,/,@lineって$i使ってないし。

で、
> ファイルにはブラウザの種類部分が何行にもわたって書き込まれてます。
というのは、
index,127.0.0.1,20060624210600,Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; SV1;
.NET CLR 1.1.4322)
こんな感じになるって意味?
0928 ◆TWARamEjuA NGNG
>>924
そうなるとせっかくの乱数が偏って、ますます乱数から遠のくかと♪
09299112006/06/25(日) 22:28:53ID:???
>>927
え?実際にそのソースで動作させた結果をお話してるのですが?
+>で読み込めますよ?
http://www.rfs.jp/sb/perl/02/08.html
それとtruncateがこの場面で必要ですか?
ヤケに煽りっぽい口調ですし・・・・単なる荒らしですか?

ちなみにアクセスログファイルには以下のように書き込まれます。

index,127.0.0.1,20060625212623,Mozilla/4.0
(compatible;
MSIE
6.0;
Windows
NT
5.1;
SV1;
.NET
CLR
1.1.4322)

ただwhileでブラウザに出力すると上記のようにはならないのでwhileだけの問題ではなさそうですが。
0930nobodyさん2006/06/25(日) 22:30:25ID:???
重複しない乱数が欲しいなら
(1)欲しい乱数の範囲を連番で配列へ格納
(2)その配列をシャッフル
これでOKよ
09319112006/06/25(日) 22:31:28ID:???
>>927
>split /,/,@lineって$i使ってないし。
あ、ありがとうございます。

・・・やっぱり普通に親切な人なのかな?
09329112006/06/25(日) 22:36:58ID:???
しかし
>split /,/,@lineって$i使ってないし。
なんでこれで動いてるんでしょうか。
ちゃんと書き込まれる内容があってるというのは不思議です。
ローカルレベルなのでipが一つだけなのでたまたま動いてるんだと思いますが。

my @temp = split /,/,@line;
これの結果って@lineをスカラで評価するわけですから、本来@tempには
数字しか入らないとおもうのですが。

なぜまともに中身が入ってるのですかね・・・
0933nobodyさん2006/06/25(日) 22:43:11ID:???
while ( <@new_line> ){

ここが原因。
<> でくくると空白ごとに改行に置換される模様。

つかですね、配列に入ってるなら
print FH @new_line;
でえぇですやん
09349112006/06/25(日) 22:52:08ID:???
>>933
空白ごとですか。
でもそれだとどうしてブラウザに出力したときは違う結果になるのでしょうか。
よければ>>925のソースにHTTPヘッダをプラスして実行してみてください。

whileでブラウザに出力してソースをみてもブラウザの種類のところに改行は
自動挿入されてないのです。

ファイルに書き込む時だけそうなってるんですよね。

確かに
$`="\n";
print FH "@new_line";
でよかったですね。
09359112006/06/25(日) 22:54:37ID:???
>>934の追記です。以下でやってみてもらえるとわかってもらえると思います。

print "content-type:text/html;charset=euc-jp\n\n";
my %access;
# どのページにアクセスしてきたか
$access{p} = ( p => "index" );
# アクセス人物のIPアドレス
$access{ip} = $ENV{'REMOTE_ADDR'};
# アクセス時刻の記録
$access{time} = sprintf "%04s%02s%02s%02s%02s%02s",sub{shift()+1900,shift()+1,@_}->(@{[gmtime(time+32400)]}[5,4,3,2,1,0]);
# アクセス人物のブラウザ
$access{browser} = $ENV{'HTTP_USER_AGENT'};
# 書込み処理
open FH,"+>access.log";
flock FH,2;
my @line = <FH>;
my @new_line = join ",",@access{qw/p ip time browser/};
for ( my $i=0; $i<@line; $i++ ){
my @temp = split /,/,@line;
if ( $access{ip} ne $temp[1] and 1000000000 > $access{time} - $temp[2] ){
push (@new_line,join (",",@temp));
}
}
while ( <@new_line> ){ print $_,"\n" }
while ( <@new_line> ){ print FH $_,"\n" }
close FH;

ブラウザでは普通に出力され、ファイルには変な改行が加えられて書き込まれます。
09369272006/06/25(日) 22:56:13ID:???
>>929
そこのサイトかー勘違いしやすい書き方なんだよな…これ。
http://pc8.2ch.net/test/read.cgi/tech/1149259409/n272-273

Perlの関数リファレンス参照
ttp://perldoc.jp/docs/perl/5.6.1/perlfunc.pod
| '+>' は最初にファイルを上書きします。
これだけじゃわかりにくいんで、もう一つ。+>のモードと言うのはfopenのw+に相当するんだが
ttp://www.linux.or.jp/JM/html/LDP_man-pages/man3/fopen.3.html
| w+ 読み取りおよび書き込みのために開く。ファイルが存在していない場合には新たに作成する。
| 存在している場合には長さゼロに切り詰められる。ストリームはファイルの先頭に位置される。
とあるように、読み込みは出来るけれど、開いたときに中身が空になる。

つまり、
my @line = <FH>;
は@lineに何も入ってきてないはず。

# 口調は雑だけど煽りのつもりは無いのでキニスンナ
# うっかり素を出すと敬語もどきになってしまうんですよ
09379112006/06/25(日) 23:17:15ID:???
>>936
なるほど!
ローカルチェックだったので初め消されても支障がなかったようです。
自分のipは一つで>>935をなんどやってもどちらにせよ中身を読み込む必要がなかったので。
splitとopenで間違いがあるのを教えてくれてありがとうございました。
すみませんあらぬ疑いを向けてしまって。質問者の分際でごめんなさいm(__)m

それでですが、本来の目的である「期待の動作をするスクリプトの作成」
からはちょっと脱線してしまってまして、なぜ>>935のソースでブラウザ出力内容と
ファイル書込み内容に差がでるのかが気になってしょうがないのですが。
>>936さんはわかりますでしょうか。

ファイルの書込みとwhileと。複雑に絡んだ現象なのでしょうか。
ちなみにperlのバージョンは5.8.1のwinxPです。
09389272006/06/25(日) 23:33:09ID:???
>>937
ブラウザではHTMLとして解釈されていると言うことを忘れているのではないか。
HTMLソースを見るか、
while ( <@new_line> ){ print $_,"<br>\n" }
while ( <@new_line> ){ print FH $_,"\n" }
とすれば同じように表示されると思う。
09399112006/06/25(日) 23:35:41ID:???
>>938
いえ、HTMLソースと書き込まれたファイルを比べて差異が出てるのです。
不思議ですよね?

さきほどから何度も>>935のソースをそのまま貼り付けて実行していますが、
何度やってもファイルの書込みの方だけ

index,127.0.0.1,20060625212623,Mozilla/4.0
(compatible;
MSIE
6.0;
Windows
NT
5.1;
SV1;
.NET
CLR
1.1.4322)

こうなってしまうのです。
0940nobodyさん2006/06/25(日) 23:41:23ID:???
なんで else if が elsif なんて珍妙な省略されてるのはどうしてだぜ?
09419272006/06/25(日) 23:53:03ID:???
>>939
ああスマソ、>>934にソース見てもと書いてあったか。
漏れのところじゃファイルに書き出された物と同様に、ブラウザの方のHTMLソースにも改行が入ってるよ。
多分、Perl上の問題じゃなくて間に入ってるウェブサーバかエディタか…ともかく環境の問題だと思う。
# それにしてもperl5.8.1って随分とまた古いものを…

>>940
else ifじゃ無いのはぶら下がりが禁止されてるから。
Cなんかのelse ifは
if (expression)
 statement;
else
 if (expression)
  statement;
と言うのをくっつけて書いてるだけだからな。しかし、elseifにしなかった訳はわからん…
言語によってelifだったりelsifだったりelseifだったり覚えるの大変('A`)
09429112006/06/26(月) 00:08:33ID:???
>>941
周辺環境によるのですか。
エディタはterapadで、apache1.3.31です。
どうやらスッキリ解決という感じにはなりそうもないですね。

ちなみに<>は空白にも反応してしまうという話ですが。
それではよくある
open FH,"hoge.txt";
my @array = <FH>;
close;

open FH,"hoge.txt";
while (<FH>){ print $_,"\n" }
close;
の精度はイマイチということでしょうか。
色々なサイトに前者の方法でファイルを読み込んで行ごとに配列に入れられる
という説明があったと思いますが。

実際は半角空白?か何かがあると行ごとにはいかないということですよね。
0943nobodyさん2006/06/26(月) 00:10:42ID:???
だからファイルハンドルじゃなくて
配列を <> に入れるとそうなるって話でしょう。
見た事無いよ <@array> なんて使い方は。
09449112006/06/26(月) 00:13:37ID:???
>>943
なるほど。
ちょっと試してみます。
0945nobodyさんNGNG
ヘタクソ!!
09469112006/06/26(月) 00:23:18ID:???
>>943
index,127.0.0.1,20060625235612,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
index,128.0.0.1,20060625235046,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)

上記がaccess.logの中身です。
open FH,"access.log";
open DH,"+>test.log";
flock DH,2;
while (<FH>){ print DH $_;}
close DH;
close FH;
上記をやったらaccess.logの中身は
index,127.0.0.1,20060625235612,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
index,128.0.0.1,20060625235046,Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)

でした。
0947nobodyさん2006/06/26(月) 00:27:07ID:???
>>912
鯖と同じOSのマシンを用意してコンパイルしてuse lib
09489112006/06/26(月) 00:27:26ID:???
上記をやったらaccess.logの中身は ではなくてtest.logの中身でした。

続き

open FH,"access.log";
my @line = <FH>;
open DH,"+>test.log";
flock DH,2;
while (<@line>){ print DH $_;}
close DH;
close FH;
今度上記をやったらtest.logの中身は
index,127.0.0.1,20060625235612,Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;.NETCLR1.1.4322)index,128.0.0.1,20060625235046,Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;.NETCLR1.1.4322)
でした。

open FH,"access.log";
my @line = <FH>;
open DH,"+>test.log";
flock DH,2;
while (<@line>){ print DH $_,"\n";}
close DH;
close FH;
最後に上記をやったらtest.logの中身は
0949nobodyさん2006/06/26(月) 00:28:23ID:???
単に while (<@new_line>) { ... } っていう変なのをやめればいいだけじゃないか。
どういう勉強の仕方したらこう書くようになるんだろう…。
ネットだけでやってきたのかなぁ。
09509112006/06/26(月) 00:28:34ID:???
index,127.0.0.1,20060625235612,Mozilla/4.0
(compatible;
MSIE
6.0;
Windows
NT
5.1;
SV1;
.NET
CLR
1.1.4322)
index,128.0.0.1,20060625235046,Mozilla/4.0
(compatible;
MSIE
6.0;
Windows
NT
5.1;
SV1;
.NET
CLR
1.1.4322)

でした。
0951nobodyさん2006/06/26(月) 00:29:19ID:???
行入力演算子(<>)を配列変数に対して使うなんて初めてみた。
普通そこはfor(foreach)じゃないの?
0952nobodyさん2006/06/26(月) 00:31:01ID:???
while (<@line>) を for (@line) にすれば済む話じゃないのか 何でこんな長々と続いてんの?
0953nobodyさん2006/06/26(月) 00:31:50ID:???
だよね。911はその書き方じゃなきゃイヤみたいなんだよ。
09549112006/06/26(月) 00:32:25ID:???
>>943
で、まとめですが。

わかったこと
@array = <FH>とやると格納されるときに行末の改行コードがなくなってる。
<@array>の時点では既に改行はない。
<@array>の中には改行は既にないが、配列の要素を一つづつ出すわけではない。

つまり<@array>なんて使うなということだと思いますが、もしかしたら
$`の区切り文字設定と同じものを見つけると<@array>これが反応する?

少し眠くなってきました。勉強になりました。
09559112006/06/26(月) 00:34:20ID:???
>>952
いえ、どうすればキチント動くかという話ではなくて、何であれであの動きをしたのかということが
気になったので。

ちなみに<@array>の方法はここで数年前にここで教わりました^^;
0956nobodyさん2006/06/26(月) 00:34:42ID:???
> @array = <FH>とやると格納されるときに行末の改行コードがなくなってる。

んなこたない
0957nobodyさん2006/06/26(月) 00:37:15ID:???
>>954
>@array = <FH>とやると格納されるときに行末の改行コードがなくなってる。
間違い。

>>948 での君のコードが間違ってる。
出力する時にまた同じく
> while (<@line>){ print DH $_;}
やってるから、この時点で空白文字(改行)がカットされてるだけ。
09589112006/06/26(月) 00:37:44ID:???
>>956
>>948を見てください。>>954は実際に動作させて得た結果のまとめのつもりです。
>>948をやると改行が全てなくなってtest.logに書かれてるということは
どこかで消されてるはずなのです。

で、それを配列に入れたときだろうと推測しました。
0959nobodyさんNGNG
そろそろ次スレ〜
09609112006/06/26(月) 00:40:05ID:???
>>957
なるほど。そこで消えてたのですか。
一応>>943を受けての一連の実験だったので、あのコードは間違いではないのですが。

しかしみなさん<@array>って本当にありえないんですね。
数年前に教えてもらってからずっと正しいやりかただと思って使ってました。
0961nobodyさん2006/06/26(月) 00:43:26ID:???
数年前からPerlやってて、+>とか<@line>とか書いちゃうのか・・・(´・ω・)
0962nobodyさん2006/06/26(月) 00:44:29ID:???
その使い方で数年間問題がなかった方が不思議だ
0963nobodyさん2006/06/26(月) 00:44:52ID:???
>>960
> 数年前に教えてもらって
((( ;゜д゜)))ガクガクブルブル

911が納得したところで次スレ建てトライしてくる。
0964nobodyさん2006/06/26(月) 00:51:24ID:???
readline 関数にファイルハンドルか型グロブ以外のものを渡した時の動作なんて
保障されてないと思うんだけど。
少なくともperldocにもラクダ本にも明記されてないね。
0965nobodyさん2006/06/26(月) 00:52:50ID:???
全く関係ない $` といい記憶違いでしょ。
どの板のスレかとその時のキーワード分かるならログから探してくるよ。
0966nobodyさん2006/06/26(月) 00:58:50ID:???
$self->{next} = new BBS2ch::Thread 'Perlコーディング初心者質問スレ Part 50';
$self->{next}->lead($self);
# テンプレ多いっす(;´Д`A
__END__
次スレ
http://pc8.2ch.net/test/read.cgi/php/1151250398/
0967nobodyさんNGNG
0968nobodyさん2006/06/26(月) 10:37:50ID:???
#!/usr/bin/>>966 -乙
package >>966;
use AutoLoader qw/AUTOLOAD/;
. . .
0969nobodyさん2006/06/26(月) 11:27:21ID:???
>>911のウザさに憤り
>>927の親切さに泣いた
そんな週末だった。
0970nobodyさん2006/06/26(月) 15:17:06ID:kXeMxgQF
<img src="hoge.cgi">

↑をHTMLに埋め込んでHTMLからhoge.cgiの呼び出しをしたいのですが、
hoge.cgi側でどこのページから呼ばれたのかを
<img src="hoge.cgi?p=index">
のようにGET形式を使わずに知ることはできますか?HTML側には
<img src="hoge.cgi">
とだけ記述で。

今初めてchatを作ってるんですが、管理者モードと一般モードとわけて機能や表示内容を変えたいのです。
それでサイト管理cgiが既に用意してあるのですが、その管理CGIから呼ばれたら管理者モード
ってことでできたらいいなと思ってるのです。

管理CGIの方はセキュリティ一応ある程度になってますので、管理CGIを開けた人間なら
いちいちそれ以上のパスなどやらないで、チャットも管理モードで動作してほしいんです。

何か方法はありますか?%ENVを見てもどうやら使えそうなのがなさそうですが。
0971nobodyさんNGNG
$ENV{"HTTP_REFERER"}
0972nobodyさん2006/06/26(月) 15:29:23ID:???
HTTP_REFERERで呼び出し元は引けるのかな?
JavaScriptのdocument.locationを使ってimgタグを生成してdocument.writeする方法はどう?
レス数が950を超えています。1000を超えると書き込みができなくなります。