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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/05/31(水) 04:32:28ID:???
Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
0200nobodyさん2006/06/06(火) 18:45:28ID:???
>>198
そういう処理が必要になった時点で何か間違ってる
0201nobodyさん2006/06/06(火) 18:46:12ID:???
>>195
そらビット演算するだろなw
やりたかったのは
if($MON =~ /^1|3|5|7|8|10|12$/)
こうだろうね
0202nobodyさん2006/06/06(火) 18:47:16ID:???
ぶw もろカッコつけるのわすれたw アホかw
if($MON =~ /^(?:1|3|5|7|8|10|12)$/)
0203nobodyさん2006/06/06(火) 18:56:40ID:???
うるう年の判定も間違ってるし日付関連のモジュールを使うべきだと思った。
0204nobodyさん2006/06/06(火) 19:04:10ID:???
>>199
も、もう少しヒントお願いします。

>>200
例えば、EXCELのフォーマットの関係でCSV出力のときだけ
こういう処理をしたりするのって変ですか?
0205nobodyさん2006/06/06(火) 19:18:40ID:???
ちょと質問です

標準入力の読み込み位置を変更したいのですが
seek STDIN, 0, 0;
ではダメなようでして
なにか術があれば教えてください
0206nobodyさん2006/06/06(火) 19:21:39ID:???
>204
1つのループでいけるかとおもったけど、前半と後半でちゃうのか・・・
処理方法を見直したほうが良いかと思うw
0207nobodyさん2006/06/06(火) 19:23:03ID:???
>>198=204
1行でもできるんでない?

ヒントをいえば、
右側は常に list[n] + list[n+5]
になってて、
その n ってのは、左側を list[i] とすれば、
i が 5回ごとに 10 足されていって、それに、 i 回目を 5 で割ったあまりを足したもの。
0208nobodyさん2006/06/06(火) 19:24:49ID:???
STDIN は前方向にしか進めないですよ

(1) 一旦ファイルに書き出したのを利用する
(2)そんなにでかくないのなら read で読み込んだものを利用する

の2通りがあります。
大きいファイル、環境にも夜でしょうが 5MB あたりを境に (1) か (2) かを使い分ければ良いかと思います。
0209nobodyさん2006/06/06(火) 19:29:08ID:???
>>208
そういうことでしたか
ありがとです
0210nobodyさん2006/06/06(火) 19:41:34ID:???
>207
あ〜、無理に $i 1つでやろうとしてたから駄目だったかw

>204
use strict;

my @list = map{ "str$_" }(0..19);

my $n = 0;
my @newlist = ();
for(my $i = 0; $i < 10; $i++){
  if($n && !($n % 5)){ $n += 5; }
  $newlist[$i] = $list[$n] . $list[$n + 5];
  $n++;
}
print join("\n", @newlist);

0211nobodyさん2006/06/06(火) 19:44:07ID:???
>>198
エレガントじゃないけど、こんなのどうかな・・・

use strict;

sub wrap_list($@) {
    my ($width, @list) = @_;
    return @list if $width <= 0 or @list == 0;

    my @result = (), my $wrap = 0, my $i = 0;
    for (@list) {
        $result[$i++] .= $_;
        if ($i % $width == 0) {
            $wrap = !$wrap;
            $i -= $width if $wrap;
        }
    }
    return @result;
}

my @wlist = wrap_list 5, ('a'..'z');
print "@wlist\n";
0212nobodyさん2006/06/06(火) 20:00:57ID:???
>>198
my @list;
for (my $i = 0; $i < 10; $i++) {
my $j = $i % 5 + 10 * int($i / 5);
$list[$i] = $list[$j] + $list[$j + 5];
}
0213nobodyさん2006/06/06(火) 20:02:43ID:???
すまん自己レス。文字列連結するのか。一行間違った。

>>198
my @list;
for (my $i = 0; $i < 10; $i++) {
my $j = $i % 5 + 10 * int($i / 5);
$list[$i] = $list[$j] . $list[$j + 5];
}
0214nobodyさん2006/06/06(火) 20:05:47ID:???
>>210-213
うはw 答え書いちゃうとわざわざヒント出した意味がww

まあありか。

自分が書いたのは >>213 まんまっす。

配列数がわからない場合、$i < 10 の部分は、事前に
my $limit = (scalar @list) / 2; で $i < $limit; とでも。 # @list は偶数であること。
02151982006/06/06(火) 20:08:34ID:???
>>207
こういうことでしょうか・・・でも結果がうまく出ないです。
どこが間違ってるんでしょうか?

for($i=0;$i<10;$i++){
if($i>=5){
$n = ($i%5) + 10 + $i;
}else{
$n = $i;
}
$list[$i] = $list[$n] . $list[$n+5];
}
0216nobodyさん2006/06/06(火) 20:09:18ID:???
>>198 は「一定の数」って書いてるから20と5はあくまで例じゃないの?
02171982006/06/06(火) 20:10:27ID:???
>>210-213
あわわ、レスあったのに気付かなくてすみませんでした!
ありがとうございます!ゆっくり拝見させていただきます。
0218nobodyさん2006/06/06(火) 20:11:28ID:???
>>215 にワロタ。
0219nobodyさん2006/06/06(火) 20:12:27ID:???
>>216
あ、ズバリその通りです。
ただ、自分の場合いきなり任意の数でできるレベルじゃなかったので・・・。
どんな数にでもすぐ応用できるものがあれば一番良いと思っています。
02201982006/06/06(火) 20:13:40ID:???
219=198です。
>>218
お恥ずかしいです・・・。
0221nobodyさん2006/06/06(火) 20:15:15ID:???
あ、>>213 よ。
$list[10] から先が残ったまんまだぞ。
まあ >>198 見ると残らせるのか残らせないのか分からないけどねw
>>198 は残らせないなら @newlist に入れるべし。
0222nobodyさん2006/06/06(火) 20:19:35ID:???
さあ、ここで拡張性のテスト
>>198の動作を、2行の折り返しから3行の折り返しにしたくなった」
「3行bヌころかn行(任意の行数)に折り返したくなった」

ちゃんと拡張できますか?
0223nobodyさん2006/06/06(火) 20:21:42ID:???
それは回答者へのテスト?w
0224nobodyさん2006/06/06(火) 20:23:45ID:???
>>223
そうw 普段から、あとで拡張しやすいように書いてますか? という抜き打ちみたいなw
02252072006/06/06(火) 20:29:44ID:???
>>222=224
んじゃ、ちょっと面白そうなのでやってみた。
>>213 に似た自分のソースでの回答w

use strict;
my $ori = 10;    # ○個ごとに折り返す (自然数)
my $ren = 4;    # 繋げる個数
my @list = map{ " $_ " }(0..119);    # @list の数は $ren と $ori の倍数であること

# loop
my @newlist = ();
my $limit = (scalar @list) / $ren;
for (my $i = 0; $i < $limit; $i++) {
    my $n = int($i / $ori) * $ori * $ren + $i % $ori;
    $newlist[$i] = '';
    for (my $j = 0; $j < $ren; $j++) {
        $newlist[$i] .= $list[ $n + ($ori * $j) ];
    }
}

# print
for (my $i = 0; $i < scalar @newlist; $i++) {
    print "$i : $newlist[$i]\n";
}
exit;

連結に2重 for 使うのはしょうがないよね・・・。
02261982006/06/06(火) 20:29:59ID:???
>>221
そうですね。その点を見落としていました。

>>222
3列の場合は・・・こう?
for (my $i = 0; $i < 30; $i++) {
my $j = $i % 5 + 15 * int($i / 5);
$list[$i] = $list[$j] . $list[$j + 5] . $list[$j + 10];
}
任意の行については・・・もうちょっと待って下さい・・・。
02272112006/06/06(火) 20:30:39ID:???
>>222
引数で$n(行数)を受け取ったとして
$wrap = !$wrap;
$i -= $width if $wrap;

if ($wrap++ < $n-1) { $i -= $width }
else { $wrap = 0; }
に直したらできます。
02282222006/06/06(火) 20:37:25ID:???
くっw 抜き打ちなのに簡単に修正しやがって!

   _、_
 ( ,_ノ` )      n
 ̄     \    ( E) グッジョブ!!
フ     /ヽ ヽ_//
0229nobodyさん2006/06/06(火) 20:38:06ID:???
>>211=227 も面白いね。考え付かないなあ・・・。
02301982006/06/06(火) 20:59:42ID:???
みなさん、すごいですねぇ。
解答を見てもよく分からない部分もあるようなレベルなので
参考にしつつ勉強してきます。
お付き合いしていただいた方々、本当にありがとうございました。
0231nobodyさん2006/06/06(火) 21:29:12ID:???
中身が数字のid.txt というファイルを読み込んで
中身を表示→数字に1を足す という動作をさせたいのですが、

中身をセットする時点で数字が消去されてしまうようです。

open (ID,">id.txt");
$id = <ID>; #ここの時点で中身が消去?

print "$id";

$id++;
print ID "$id";
close(ID);

例えばファイルの中身の初期値が100ならば、
最初は100、リロードの度に101、102・・・と表示されると思うのですが
上手くいきません。

ご指摘のほどよろしくお願いいたします。
0232nobodyさん2006/06/06(火) 21:35:14ID:???
>>231
>open (ID,">id.txt");
書き込みでopenしているので、中身はこの時点で消去です。
一度読み込んでから、書き込むように変えましょう。
0233nobodyさん2006/06/06(火) 21:35:56ID:???
>>231
openのモードがNG
「>」「>>」「<」「+<」の違いはわかってる?
0234nobodyさん2006/06/06(火) 21:41:43ID:???
+< id.txt
seek
減る事もある場合、桁数に注意
0235nobodyさん2006/06/06(火) 23:19:31ID:???
ねえ、
$word が任意の入力できる文字列で、文字コードが EUC か UTF8 だとして、

$word = quotemeta $word;
$word =~ /$word/;

に、セキュリティホールってある? 普通に通るかすら。
0236nobodyさん2006/06/06(火) 23:22:01ID:???
なんで $word を $word で検索してんだw
$word = quotemeta $word;
$text =~ /$word/;
こうですた。
0237nobodyさんNGNG
何がしたいねん
0238nobodyさん2006/06/06(火) 23:43:29ID:???
おそらくは検索か
俺は\x00-\x19までを削除してるのと、正規表現で意味のもつものをエスケープする以外はなんもやってない
0239nobodyさん2006/06/07(水) 00:01:52ID:Z9iT2VzK
勉強中の身に、どなたか教えてください。

open(FILE, "<2get.txt") || print "file open error!";
while(<FILE>){
print;
}

とやって、2get.txtの内容を出力する、というのを応用して、
2get.txtの内容を途中まで読み込むCGIを作りたいのですが。

例えばこの2get.xtxの中の1行に、
<!-- ここまで -->
とか書いておきます。

で、CGIで読み込む時に、上から1行ずつ読んでいって
<!-- ここまで -->の行が出てきたら、読み込み終了。

実際に自分で作ってみて、while〜の1行を
while(<FILE> ne '<!-- ここまで -->') ||(以下略)
って書き換えたら、CGIが動かなくなりますた。
どっかで勘違いしてるんだろうと思うんだけど、
勘違いのポイントかヒントだけでも教えてください。
0240nobodyさん2006/06/07(水) 00:16:13ID:???
while(<FILE>)ってwhile($_ = shift <FILE>)と同じなんで、そこで抜ける判定をしなんでも
print; の前に抜ける条件を書いて lastしてみればいいんじゃないかと。
0241nobodyさん2006/06/07(水) 00:41:37ID:DSNCvTMF
勘違いじゃなくて勉強が足りんかったわけですね。
つーか500エラーが出ました。

while(<FILE>) {
if($_ eq '<!-- ここまで -->') { last; }
print;
}

これで合ってますか?
0242nobodyさん2006/06/07(水) 00:47:38ID:DSNCvTMF
あ、できた。

でも<!-- ここまで -->を読んでくれません。
''で囲むんじゃダメなんですかね?
それとも改行コードも考慮しないといけないとか?
0243nobodyさん2006/06/07(水) 00:47:47ID:???
>>240
shift はつかなくね? $_ = <FILE> じゃ?
0244nobodyさん2006/06/07(水) 00:49:12ID:???
>>242
$_ は最後の行じゃない限り、最後に改行がついてるよ
0245nobodyさん2006/06/07(水) 00:51:05ID:???
>>232>>233>>234
有難うございました。

0246nobodyさん2006/06/07(水) 00:59:40ID:???
>>243
defined($_ = <FILE>) じゃね?
0247nobodyさん2006/06/07(水) 01:03:44ID:???
でもさあ、1行ずつ読み込んで、その都度あるかないかわからない文字列をチェックして途中で終了させるより、
一気に全部読んで文字列に入れてから、その文字があるなら正規表現でずばっと削除したほうが早いよね。
0248nobodyさん2006/06/07(水) 01:09:16ID:???
>>247
んなこた環境とデータセットによる。
0249nobodyさん2006/06/07(水) 01:11:19ID:???
I/Oやメモリをそこまで気にする時代じゃないだろうに
02502482006/06/07(水) 01:18:21ID:???
>>249
「早いよね」ってことだったので、速いか遅いかは読込むデータの傾向や動作環境によるっつー話。
メモリやら I/O の話はどこから出てきた?
0251nobodyさん2006/06/07(水) 01:20:34ID:???
っていうか、いま気づいたんだけど、
>>239 の場合

local $/ = '<!--ここまで-->';
open (FILE, '2get.txt');
$_ = <FILE>;
close (FILE);
print $_;

ってやると解決しないか?
速度的にも一番早い。
0252nobodyさん2006/06/07(水) 01:23:04ID:???
>>240
>>244
ありがとうございました。なんとか動くものになりました。

>>247
正規表現もまだ理解しきっていないので…
今後のメンテナンスの時に考えることにします。
02532512006/06/07(水) 01:24:25ID:???
あ、 print 前に chomp; もか。
0254nobodyさん2006/06/07(水) 01:29:15ID:???
>>251
激しく意味不明のテキストが発生しますた…
0255nobodyさん2006/06/07(水) 01:38:27ID:???
>>254
まじでwww
うちではうまくいくけどなあ。
ちょっとこれだけ走らせてみt

[2get.txt]
1111111111111111111111111111111111111111111
222222222222222
3333333<!--ここまで-->333333333333

[hoge.pl]
use strict;
{
local $/ = '<!--ここまで-->';
open (FILE, '2get.txt');
local $_ = <FILE>;
close (FILE);
chomp $_;
print $_;
}
exit;

\r\n\r\n ずつデータとるときとかに使えるしwktkだと思ったんだがなあ。
0256nobodyさん2006/06/07(水) 01:43:22ID:???
$/ 自体に長さの制限とかあるのかな?
0257nobodyさん2006/06/07(水) 01:52:11ID:???
>>256
どうなんだろ?
とりあえず試しに 200kb くらいのテキスト用意して、

- - - - - - - - - - - - - - - - - - - - - - - - - - -
$/ = '『根掘り 葉掘り 聞き回る』の・・・『根掘り 葉掘り』・・・・・ってよォ〜〜〜
『根を掘る』ってのはわかる・・・・・スゲーよくわかる 根っこは土の中に埋っとるからな・・・
だが「葉掘り」って部分はどういう事だあああ〜〜〜〜〜っ!?
葉っぱが掘れるかっつーのよーーーーーーッ!
ナメやがってこの言葉ァ 超イラつくぜぇ〜〜〜ッ!!
葉っぱ掘ったら裏側へやぶれちまうじゃあねーか!
掘れるもんなら掘ってみやがれってんだ!チクショーーッ
どういう事だ!どういう事だよッ!クソッ!葉堀ってどういう事だッ!
ナメやがってクソッ!クソッ!';
- - - - - - - - - - - - - - - - - - - - - - - - - - -

・・・って入れてやってみたけど、こっちでは無事その前部分だけに切り取られたよw
0258nobodyさん2006/06/07(水) 01:52:17ID:???
>>255
ファイル作ってみましたが500エラーです…

おかすい。なぜだ。
0259nobodyさん2006/06/07(水) 01:59:10ID:???
>>258
え、どんなエラーでてる?

ブラウザでやってるなら
#!/usr/bin/perl
print "Content-type: text/html\n\n";
も入れてね?
0260nobodyさん2006/06/07(水) 02:03:21ID:???
>>257
その文章の方が気になりますがw

すんません、Content-typeを入れるの忘れてますた。
んで、今度こそ大丈夫だと思ったら空白ページ。

鯖環境かなんかですかね?
0261nobodyさん2006/06/07(水) 02:07:38ID:???
できたー!
0262nobodyさん2006/06/07(水) 02:11:01ID:???
ええw ('A`)

まあおめでとう!w 何が悪かったのやらw

てか自分のPCに perl 入れて、コマンドプロンプトとかから perl 実行すること覚えようぜ。エラーメッセージでて便利よ。
0263nobodyさん2006/06/07(水) 02:14:36ID:???
> てか自分のPCに perl 入れて、コマンドプロンプトとかから perl 実行すること覚えようぜ。エラーメッセージでて便利よ。

無限 fork するようなもの書いたときにおかしくなるから嫌。
0264nobodyさん2006/06/07(水) 02:14:53ID:???
>>262
うい。perlは入れた(はず)ですが、実行の仕方(設定の仕方?)が分からんとです。
これから覚えます。

ちなみに、もともと作ってた方のページも直しましたが、
読み込み元ファイルの内容が表示されんとです。

まだまだ道は長いとです。

ありがとうございました。
0265nobodyさん2006/06/07(水) 02:19:08ID:???
>>263
えぇw

>>264
そのフォルダからcmd開いて、 「perl hoge.cgi」 とか打つだけだす。
あと、$/ 変えて読み終わったあとは、変な挙動起こさないように、
$/ = "\n"; って設定しなおしていくといいかも。
0266nobodyさん2006/06/07(水) 02:23:00ID:???
>>265
> そのフォルダからcmd開いて

いきなり意味分かんないんで、このスレのログ保存しておきました。
もうちょっと頭が良くなってから読み返します。

こんな夜中までありがとうございます。
0267nobodyさん2006/06/07(水) 02:29:37ID:???
>>184 ありがトン
0268nobodyさん2006/06/07(水) 02:37:25ID:???
> そのフォルダからcmd開いて

確かに、意味不明ですね。
0269nobodyさん2006/06/07(水) 03:07:49ID:???
意味不明だけど言いたいことは分かる
0270nobodyさん2006/06/07(水) 03:08:00ID:???
まじかw

↓こういうのをやるとか、
http://arena.nikkeibp.co.jp/tec/winxp/20050309/111687/

どっかのフォルダの ツール → フォルダオプション → ファイルの種類 → CGI ファイル → 詳細設定 で、
新規 → アクション 「cmd」 → アクションを実行するアプリケーション 「cmd.exe "cd %l"」

ってやると、「そのフォルダからcmd開いて」 な感覚になるんだけど・・・普通そう言わないのかな・・・(´・ω・`)
0271nobodyさん2006/06/07(水) 04:27:27ID:???
アクセサリ -> コマンドプロンプト を実行して、
cd "c:\perlスクリプトがあるディレクトリ"
perl スクリプト名.pl

が親切では?
0272nobodyさん2006/06/07(水) 05:24:07ID:???
>>271
うん、そうなんだけど、
ファイルのディレクトリが D:ドライブだとまた違うし、
何度も使うなら、cd 〜フォルダ名 とか打つの省略できる方が楽だと思って。
0273nobodyさん2006/06/07(水) 05:51:48ID:???
>>272
今日から perl 勉強します yo! ってひとが、そんな設定やると思う?

コマンドプロンプト開いた時点で、その人のホームディレクトリにいるから
誘導するのはそれほど難しくないよね。
0274nobodyさん2006/06/07(水) 08:11:05ID:???
Microsooftが配布してるツールとか、窓の手とかのカスタマイズツールで、
エクスプローラのフォルダから DOS 窓を開けるようになる。
そうすれば一々 CD しなくてもいいし、perl への PATH が通ってれば perl ってだけで
起動できる。

ちなみに cmd とか commasnd とかから起動すると速攻で窓閉じるから駄目よw
0275nobodyさん2006/06/07(水) 10:29:37ID:???
あるソースを読んでいて分からないところがあるので質問させて下さい。

@{$a}{@$b}

これってどういう意味なんでしょう?
そんなに難しいことじゃないと思うんですが、
perlは慣れていないので苦労しています。
宜しくお願いします。
0276nobodyさん2006/06/07(水) 10:44:11ID:???
>>275
例えば、
$a = 'hash';
$b = ['a', 'b']; # 配列のリファレンス
とすると、
@{$a}{@$b} → @hash{'a', 'b'} → ($hash{'a'}, $hash{'b'})
のこと。
02772752006/06/07(水) 10:54:10ID:???
>>276さん
そういうことだったんですね。
助かりました。有難うございました。
0278nobodyさん2006/06/07(水) 13:05:38ID:???
配列とソートに関しての質問です
左は日付です

--20060101--aaaa----
--20060423--bbbb----
--20060514--cccc----

なんてのが書いてあるファイルを読み込み @dataとします
まず@dataを表示させてみると2行目からの頭に半角のスペースが入ります
これはなんでしょうか?

さらに

foreach(@data){
if( /(--(\d*)--\w*----)/){
$list {"$2"}=$_;
}}

foreach $key (sort keys %list){
push @htm ,$list{$key};}

とし、これをもう一度展開して表示させてみると、同じ日付がある場合に
誤動作して読み込まれません
改善するにはどうしたらいいでしょうか?
0279nobodyさん2006/06/07(水) 13:14:37ID:???
>>278
行と改行コードに関する質問です

読み込み
もう一度展開

なんてのが書かれている質問を読み込みます
これはなんでしょうか?

> 頭に半角のスペースが入ります
> これはなんでしょうか?
 自分で書いているとおり半角のスペースなのではないでしょうか。

さらに

誤動作して読み込まれません

と書いてあるので考えてみると、コードは動いているのに質問する場合なので
解釈がうまくできません
改善するにはどうしたらいいでしょうか?
02802782006/06/07(水) 13:20:29ID:???
質問の仕方が悪いのはご容赦ください
0281nobodyさん2006/06/07(水) 13:28:36ID:???
>>278
> 半角スペース
定番FAQ
print "@data";とやってるだろ。
配列を文字列内に入れようとすると$"(デフォルトで半角スペース)で連結されるからこうなる。
むやみにダブルクォーテーションで囲むのは止めましょう。
ちなみにprint @data;の場合は$,で連結される。これはデフォルトで空文字列。

> 同じ日付
%listの中に配列を作って複数の値を記録できるようにすれば良い。
foreach (@data) {
push @{$list{$1}}, $_ if /--(\d*)--\w*----/;
}

foreach my $key (sort keys %list){
push @htm, @{$list{$key}};
}
0282nobodyさん2006/06/07(水) 13:29:56ID:???
>>278
@dataはファイルから丸ごと読み込み
@data = <FH>;
で、@dataを表示する時に
print "@data";
とかやってるんじゃないの?
だったら頭にスペース入るだろうね。

2つめは当たり前でしょう。
同じ日付があれば、データが上書きされるので。
ハッシュの先を配列にするとかしないと。
0283nobodyさん2006/06/07(水) 14:35:06ID:CY60cgj5
wiki記法で書いたテキストをhtmlに反映したいのですけど
そういったモジュールってありますでしょうか?

CPANでwikiで検索したら数があまりに多すぎて。。。。。

02842782006/06/07(水) 14:55:55ID:???
>>281 >>282
有り難うございます

push @{$list{$1}}, $_ if /--(\d*)--\w*----/;
この部分がエラーを発生します

もうちょっと勉強してみます
02852782006/06/07(水) 14:57:52ID:???
失礼しました、大丈夫でした、m(_ _)m
0286nobodyさん2006/06/07(水) 16:04:17ID:???
それだと要素数が1の配列ができまくってモヤっする
0287nobodyさん2006/06/07(水) 16:08:10ID:???
文法的に正しいとか間違ってるとかは置いといて、スカラーとか配列とか、
最初に空のデータとして宣言しとかないと何か不具合起こすことってあるの?
0288nobodyさん2006/06/07(水) 16:22:34ID:???
>>287
Cみたいに初期化しないと変な値が書き込まれてるって事は無い。

ただし、配列かどうか分からない所にいきなりpushしたりするとエラーになる。

my %hash;
my %data = ('a' => 1, 'b' => 2, 'c' => 3);
while (my($key, $val) = each %data) {
 push($hash{$key}, $val); # Error(配列に初期化してないから)
}
0289nobodyさん2006/06/07(水) 16:25:30ID:4ldG4rWr
winxp
perl5.8.8

ウェブ上で使ってるプログラムをローカルに持ってきたらエラーがでました。
ウェブのperlは5.8.1です。
そこで質問です。

use strictしてるプログラムをperl -cに掛けてエラーが出ないのにapacheのログに
[Wed Jun 07 16:06:23 2006] [error] [client 127.0.0.1] Premature end of script headers: c:/program files/apache group/apache/htdocs/public_2/system/system.cgi
[Wed Jun 07 16:06:23 2006] [error] [client 127.0.0.1] Can't use an undefined value as a HASH reference at c:\\PROGRA~1\\APACHE~1\\apache\\htdocs\\public_2\\system\\system.cgi line 427.\n
と出て、strictを外すと
[Wed Jun 07 15:47:53 2006] [error] [client 127.0.0.1] Premature end of script headers: c:/program files/apache group/apache/htdocs/public_2/system/system.cgi
[Wed Jun 07 15:47:53 2006] [error] [client 127.0.0.1] substr outside of string at c:\\PROGRA~1\\APACHE~1\\apache\\htdocs\\public_2\\system\\system.cgi line 445.\n
とエラー内容が変わるのはなんですかね。

ウェブ上ではなんのエラーもなく動作してる時点でコードに問題はないと思うのですが。
0290nobodyさん2006/06/07(水) 16:28:46ID:???
>>288
ほぉ、なるほど、そういうケースがあったのね。
勉強になりました。ども。
0291nobodyさん2006/06/07(水) 16:28:50ID:???
>>289
apachのえらーろぐみたらえーやん。
0292nobodyさん2006/06/07(水) 16:30:26ID:???
>>289
use strict; してるかどうかによって警告が出る位置が違ってる。
それから、エラー読もうよ…。
substr が文字列境界超えてるって。

多分、見えないだけで、webサーバ側のログには延々とそれが書き込まれてる。
02932892006/06/07(水) 16:40:43ID:4ldG4rWr
>>291
すみません。先ほどのapacheのエラーログです。
>>292
文字列境界越えてるって使い方がおかしいってことですかね。<strong>${\substr($db_all_field_html{ordertime},0,4)}年${\substr($db_all_field_html{ordertime},4,2)}月${\substr($db_all_field_html{ordertime},6,2)}日
こういうことはしてます。でもウェブの方ではエラーログには何も残らず、ちゃんと表示される。
自宅では表示もできないし、ログにも
残る。

それにしても構文レベルのエラーならperl -cでひっかかると思ったのですが、
構文はあっているけど、実際に処理をしたら無理だった。とかあるんですかね?
それでウェブの方では実際にやっても大丈夫だったけど、自宅の法では実際に無理だったみたいな誤差ですかね。

strictを外すとエラーの行が変わるのは気づいてたのですが、どうも構文チェックがokでてる以上
何をすればいいかわからなくて。
0294nobodyさん2006/06/07(水) 16:41:02ID:???
>>288
僕の個人的かつ大胆な推測によると、
仮に $hash{$key} の値を配列リファレンスで初期化していたとしてもエラーが出ると思うのだ。

それ、デリファレンスしてねえからな。
02952942006/06/07(水) 16:48:28ID:???
補足:
未初期化なナニをデリファレンスすると、perl はその時点から「そのように」扱ってくれる。
だから >>288 のようなケースでは個別の初期化は不要。いや、してもいいけどさ。
0296nobodyさん2006/06/07(水) 17:09:37ID:???
>>294
その通りだw
0297nobodyさん2006/06/07(水) 17:10:08ID:???
>>293
何か値が入るとあなたが仮定している変数が、どこかで undef ってると思われます。
それぞれのタイミングで各変数の値が期待通りになっているかチェックしましょう。。

-c スイッチの syntax OK は 「perl によって曖昧さなくパースできますよ。一応ね」 という意味なので、セマンティクス上のバグは見つけてくれません。
代わりに -wc を使うようにすると警告も併せて示してくれます。
0298nobodyさん2006/06/07(水) 17:15:43ID:???
てかこれ、他人のサーバにエラーログを延々と残す迷惑な奴の典型例だな。
02992892006/06/07(水) 17:20:02ID:4ldG4rWr
>>297
ありがとうございます。
-wcやってみます。

とりあえずsubstrのあの記述を抜いて、strictを外すと表示ができるようになりました。
今はstrictでない部分を探してます。

ところでもしかして、5.8.1と5.8.8では何か違うんですかね。そう思えてならないです。
5.8.1が手に入ればわかりやすいですが。
■ このスレッドは過去ログ倉庫に格納されています