Perl コーディング初心者質問コーナー Part26
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
03/07/24 19:48ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
関連スレ
【Perl上級者コーナーPart01】
http://pc2.2ch.net/test/read.cgi/php/1024741312/
CGI: Common Gateway Interface part 11
http://pc2.2ch.net/test/read.cgi/php/1055597189/
【Perl,CGI】参考書籍 第三版
http://pc2.2ch.net/test/read.cgi/php/1030209573/
【 スクリプト改造工房 PART 6 】
http://pc2.2ch.net/test/read.cgi/php/1047806915/
過去ログやお勧めサイトは >>2-10
0461457
03/08/04 16:48ID:???# つか捻りの無いソフト名多すぎ:)
だな。俺もさっき調べてたけどWindiffって名前で色んな奴があるよな。
Cygwin入れてるから別にいいんだけどな。
0465nobodyさん
03/08/04 20:06ID:???漏れもうすぐネカフェの時間なので
0466あぼーん
NGNG0467あぼーん
NGNG0468あぼーん
NGNG0469nobodyさん
03/08/04 20:47ID:???負荷を考えると、ループの中でevalを使いたくないのです。
(ループさせる回数がとても多いので。)
現状では、こういう風にやってます。
eval('use Time::HiRes;');
if ( $@ eq undef ) {
require './lib/bench.pl';
$HIRES = 1;
&bench::start;
} else {
require './lib/dummy_bench.pl';
}
最初にこういう風にしておいて、
続く
0470nobodyさん
03/08/04 20:47ID:???package bench;
use strict;
use Time::HiRes;
sub start {
処理ほげほげ
}
sub check {
処理ほげほげ
}
1;
dummy_bench.plの中身は
package bench;
sub start {
}
sub check {
}
1:
Time::HiResが必要な処理の時は
&bench::check
等として呼ばれるわけですが、最初のevalのチェックで失敗してたら
ダミーのほうが読み込まれているので空のサブルーチンが呼ばれます。
このやり方について2点疑問があります。
1.ファイル名とパッケージ名は同一でなければならないと聞いたことがありますが、これはやってはいけない方法なのですか?
2.もっとスマートな方法があるならご教授ください。
0471nobodyさん
03/08/04 20:54ID:???0472nobodyさん
03/08/04 21:40ID:???1. 自分が何をやっているのか理解しているなら問題ない。
2. Time::HiRes の存在チェックを bench.pl 内でやれば
dummy_bench.pl は不要。
#--- Bench.pm ---
package Bench; # 小文字のみのパッケージ名はプラグマ
use strict;
eval ('use Time::HiRes;');
my $EnableHiRes = $@ ? 0 : 1;
sub start;
*start = $EnableHiRes ? sub { ... } : sub { ... };
#--- Bench.pm を使うスクリプト ---
use Bench;
Bench::start();
0473469
03/08/04 21:50ID:???とてもためになります!
これがきっかけで
ついでにいろいろ気になることも増えてきたので
勉強中です。。
0474469
03/08/04 23:32ID:???サブルーチンの定義自体をevalしないと
モジュールがないとき動きませんでした。
sub start;
*start = $EnableHiRes ?
eval 'sub { use Time::HiRes; ほげほげ }' : sub {};
#単純にevalの中でuseしてもされてないのでこうするしかないような
0475nobodyさん
03/08/05 00:29ID:???何故また use し直すんだ? 下のコードで試してみ。
Time::HiRes が存在すれば実際に sleep した時間が、
無ければ常に 1 が返ってくる。
#--- Stop.pm ---
package Stop;
use strict;
eval('use Time::HiRes qw(usleep);');
my $Enable = $@ ? 0 : 1;
sub stop;
*stop = $Enable ? sub { usleep($_[0] * 1_000_000) } : sub { sleep($_[0]) };
1;
__END__
#--- test.p ---
#!/usr/local/bin/perl
use strict;
use Stop;
local $| = 1;
print 'foo,';
my $wait = Stop::stop($ARGV[0]);
print "bar. ($wait)\n";
__END__
0476469
03/08/05 01:03ID:???まじすいませんです。
475のコードでもいろいろやってみました。
evalしないと動かなくなっていたのは
以後の処理のほうに問題があるっぽいです。
あるっぽいというのは、最小限の部分だけコード取り出して
いろいろ試してたら今動いたので。
これからじくーり調べます。
ほんとたすかりました。
0477nobodyさん
03/08/05 01:12ID:???if (require Time::HiRes) {
$Enable = 1;
Time::HiRes->import('usleep');
}
0478nobodyさん
03/08/05 05:31ID:???具体的には
「日本語 ファイル名テスト用ファイル.txt」を
%C6%FC%CB%DC%B8%EC%20%A5%D5%A5%A1%A5%A4%A5%EB%CC%BE%A5%C6%A5%B9%A5%C8%CD%D1%A5%D5%A5%A1%A5%A4%A5%EB.txt
このようにしたいのです、変換元の日本語はEUC(自身無い)です
今、他人のCGIをいじっているのですがそもそも反対のことをしているのはわかっているのですが
うまく、上の形になりません、何か効率のいい方法はありませんか?
0479478
03/08/05 05:33ID:???>うまく、上の形になりません、
うまく、上の形の文字列が取得できません
0480nobodyさん
03/08/05 06:02ID:???$str =~ s/(\W)/'%'.unpack("H2", $1)/ego;
print $str;
0481nobodyさん
03/08/05 10:33ID:???と
eval('use Time::HiRes;');
は何が違うの?
0482nobodyさん
03/08/05 11:03ID:???前者は実行できなかった時にコンパイルエラーになる。
後者は実行できなくてもそのまま進む。
0483nobodyさん
03/08/05 11:28ID:???俺の実力では原因が特定出来ないので相談にのってもらいに来ました。
ファイルの書き換えなのですが、日頃正常に動いていた動作で、
突然ファイルの中身が消滅してしまい、「0バイトのファイル」になってしまいました。
記述内では、ファイルを書きかえる処理として、
open(FILE,">$log_file");
print FILE $log_code;
close(FILE);
このようなもの「のみ」あり、$log_codeには必ず何かが代入されています。
$log_code に何かが代入されているのはこのプログラムの基本で、代入されていないわけはありません。
また、今回発生したバグと同一の処理は日頃から普通に行っていました。
また、このファイルは複数人数が書き換える物ではなく、
ID登録した「一人の人物」が書き換えるものなので、ファイルロックなどはしていませんでした。
今回のバグで、ファイルの中身が消滅してしまう原因となったアクセス者は、
「俺自身」です。
プログラム作者は俺自身なので、微妙に動作は怪しいですが、今回のは想定外のバグで、原因がつかめないでいます。
記述を考えても、処理自体のバグでファイルが消えてしまった事は非常に考えにくいのですが、
これは取り敢えず、
「処理自体のバグ」を疑うべきでしょうか?
「システムのファイル書き換えミス」を疑うべきでしょうか?
m(__)m
0484あぼーん
NGNG0485nobodyさん
03/08/05 11:55ID:???デバッグにおいてこういう思い込みは最大の敵。
必ずテストを行ない、その結果を確認する事。
この場合なら、openの前後の行にprintで$log_codeを表示させてみる。
はっきり言えば、>483の説明だけではなんとも言えない。
情報が少なすぎる。
0486nobodyさん
03/08/05 12:24ID:???die "Error : \$log_code" unless ($log_code);
とか
これを機にいろいろトラップしとき
0488nobodyさん
03/08/05 14:17ID:???両者の違いは、一気に構文解析がされるかされないか。
eval BLOCKの場合はそうされるので、eval 文字列よりも高速
0489483
03/08/05 14:46ID:???ありがとうございます。
同じように再現しようと思っても日頃からやってるのと同じ処理なので困ってました。
今度から、ことごとくプログラム内でエラーチェックしておくようにします。
バグの原因が分からない時ってスッキリしないですね。。。。汗
0490nobodyさん
03/08/05 16:01ID:???超高速でダブルクリックして呼び出しかけたらどうなんねん?
0491nobodyさん
03/08/05 17:42ID:???クレス
0493492
03/08/05 18:45ID:???もうひと言付け加えると今まで正常に動いていたのは$log_fileが軽かったから。
$log_fileのサイズが臨界点に達すると、鯖がいい加減にしろと作業途中で職場放棄。
0494483
03/08/05 20:36ID:???みなさんありがとうございました。
大変参考になりました。
>>492
それを回避するには、ファイルを2つ用意し、バックアップも常に生成しておけ…
と言う事でしょうか?
0495nobodyさん
03/08/05 20:58ID:???0496nobodyさん
03/08/05 21:07ID:???0498nobodyさん
03/08/05 22:11ID:???どのくらいよ?
0499nobodyさん
03/08/05 22:25ID:LRtAIpMcmy $et = int(rand(9));
if($et == 3){
srand(time|$$);
$et =int(rand(2)) ;
if($et == 0) {
@
}else{
A
だと、全部@になります。
2つ目の srand(time|$$); を無くすと、
正常になりますが、どうしてでしょうか?
0500nobodyさん
03/08/05 22:25ID:???排泄処理…?プロセス事故死の話だろ?
>>494が正解。
ただlogを毎回自動バックアップしてたら壊れたファイルも…ってことになるから、
その変自分のにあったうまい方法を考えておく事。
>>498
perlのメモリ管理はperl自身でやっているから、
つまり鯖によって設定が(ry
0501nobodyさん
03/08/05 22:29ID:???なんで2回も初期化してるのかは知らんけど。
randの出しかたはアルゴリズムがマシンによって違うぞ。
俺の勘では、それwin系のシステムで使ってないか?
0502あぼーん
NGNG0504nobodyさん
03/08/05 23:34ID:???これを動かしてみそ。
srand(time|$$);
my $base = rand;
print "base = ", $base, "\n";
srand(time|$$);
print "base*3 = ", $base*3, " rand(3) = ", rand(3), "\n";
srand(time|$$);
print "base*2 = ", $base*2, " rand(2) = ", rand(2), "\n";
しかし、srand(time|$$)って、Win系だと数列がほとんど変化しない予感。
0505あぼーん
NGNG0507504
03/08/06 01:10ID:???処理系によるかもしれませんが、大抵、srandに同じ乱数シードを与えると
randで読み出す乱数列が同じ物になります。
>>499の複数回のsrand(time|$$)で、$$(プロセスナンバー)は変化しません。
timeは一秒ごとに更新なので、これもほとんど変化しません。
つまりrandの前でsrand(time|$$)を実行することによって、(かなりの確率で)
同じ数列を読み出してることになります。
rand(n)はrand()*nと(最低でもperl5.005_03以降は)等価なので、
int(rand(9))==3が成り立ちrand()値が同じ場合、rand(2)で得られる値は
3.0/9*2=0.666..から3.999../9*2=0.888..までの値になります。
よってint(rand(2))で得られる値は常に0になります。
…多分ね。
0508nobodyさん
03/08/06 09:23ID:7imIHn2Wパッケージ($package)のシンボルテーブルを、%stabで参照できるようにする
コードとして、赤ラクダ本に次のように書いてありました。
local(*stab) = eval("*_$package");
(*_$packageの部分は、Perl5では、*{${package}::}だと思います。)
このevalは何をしているのでしょうか? あっても、なくても同じでしょうか?
perl4ではシンボリックリファレンスは使えなかったから、eval()が必要だった。
今ではわざわざeval()する必要はないね。
ついでに型グロブで別名をつける必要も無い。
my $stab_ref = \*{$package."::"};
これでシンボルテーブルへの参照を直接使えばいい。
0510nobodyさん
03/08/06 10:57ID:7imIHn2Wどうも有り難うございます。でも、Perl5でシンボリックリファレンスを使え
ないようにして、しかもevalなしでも動いてしまうのが不思議です。
use strict 'refs';
$package = 'main';
local(*stab) = "*${package}::";
while (($key, $val) = each(%stab)) {
local(*glob) = $val;
if (defined $glob) { print "$key => $glob\n"; }
}
あ、ホントだ。
多分、perl5からだと思う。
でも折角のstrict 'refs'なのに…変な仕様だね。
0512nobodyさん
03/08/06 11:45ID:JjxVikEHフォームから取り入れた情報にファイルを書き換えるコードを書いたんです。
そしたらその書き換えるファイルを開こうとしてもそのOPEN行でエラーが起こってしまうんです
どうしたらいいのでしょうか
open(FILE,"+<$fileini");
ご要望ならソースコードの一部または全部を載せますが・・・。
誰か教えてください。
0513nobodyさん
03/08/06 12:55ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
0514nobodyさん
03/08/06 13:11ID:???だってさ。
しかも、「ご要望なら」ソースを見せますが。だってさ。
誰の要望だよ。
ちなみにそのopenは書式ミスしてないよ。
0515nobodyさん
03/08/06 13:13ID:???Perlは変数の大きさを勝手に制限するような事はしないから、
Perlの設定や、鯖の設定(もしかしてこれは資源の制限値?)には関係なく、
Perlが取れる最大のメモリが影響する。
>>498
CGIとして動かすなら、ブラウザのタイムアウトでプロセスが殺されるという限界になるはず。
0516nobodyさん
03/08/06 13:15ID:???0517nobodyさん
03/08/06 13:19ID:???0518nobodyさん
03/08/06 13:40ID:???「CGI signal タイムアウト」でググってみ。
書籍があるならsignalの章を見てもいいぞ。
て、ここperlコーディングスレじゃん....
0519512
03/08/06 14:37ID:JjxVikEHHPの諸設定の書き換えがしたくてCGIをコーディングしたんですが
フォームで設定ファイルを書き換える段階まで来て、
このOPEN行で
Unterminated <> operator at administrator.cgi line 194.
ってでるんです。194行目は open(FILE,"+<$fileini"); です。
0520あぼーん
NGNG0522519
03/08/06 15:03ID:JjxVikEHそれでいけるんですか!?
0523519
03/08/06 15:06ID:JjxVikEHScalar found where operator expected at administrator.cgi line 194, at end of li
ne
syntax error at administrator.cgi line 194, near "open(FILE,"$fileini"
String found where operator expected at administrator.cgi line 201, near "print
FILE ""
(Might be a runaway multi-line "" string starting on line 194)
(Missing semicolon on previous line?)
Backslash found where operator expected at administrator.cgi line 201, near "pri
nt FILE "\"
(Do you need to predeclare print?)
syntax error at administrator.cgi line 227, near "}"
administrator.cgi had compilation errors.
0524nobodyさん
03/08/06 15:08ID:???local(*stab) = *{"${package}::"}; # シンボリックリファレンス
local(*stab) = "*${package}::"; # シンボリックリファレンスではない
$pkg = 'ABC';
print "*${pkg}::"; # *ABC::と表示
print eval("*${pkg}::"); # *main::ABC::と表示、何でこうなるかは不明
0525336
03/08/06 15:11ID:???とりあえず削除してみてどうなるのか確認したかった。
どっか前の行で"を付け忘れたりとかそんなミスじゃないの。
0528519
03/08/06 16:00ID:JjxVikEH一応一通り見てみたんですけど、おかしいとこはなかったんです。
sub formset {
# フォームデータ取得
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {
$query="$ENV{'QUERY_STRING'};
}
# フォームデータ復元
foreach $pair (split(/&/, $query)) {
($key, $value) = split(/=/, $pair);
# 文字のデコード
$value =~ tr/+/ /;
$value =~ s/%[0-9a-fA-F][0-9a-fA-F]/chr(hex($1))/eg;
$foem{$key} = $value;
}
# ファイル出力
open(FILE,"+<$fileini");
seek(FILE,0,0);
foreach $key (sort keys %form) {
print FILE "\$$key=\"$form{$key}\"\;\n";
}
# ファイルを閉じる
close(FILE);
}
これがこのコードの入ったサブルーチンです。
このルーチンを抜いてチェックしてみたらsyntax OKでした。
0529519
03/08/06 16:01ID:JjxVikEH0530nobodyさん
03/08/06 16:04ID:???0532あぼーん
NGNG0533519
03/08/06 16:20ID:JjxVikEH今の今までまったく気がつきませんでした。
syntax OK出ました!!
ありがとうございました!
0534nobodyさん
03/08/06 17:11ID:???0535nobodyさん
03/08/06 17:51ID:???0536nobodyさん
03/08/06 18:27ID:???0537nobodyさん
03/08/06 18:34ID:???$query="$ENV{'QUERY_STRING'};
.....次の " を探し中....
open(FILE,"+<$fileini");
ビクッ. ∧ ∧ ∧ ∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
Σ(゚Д゚;≡;゚д゚) < うおっ、 " がでてきたが、なんかすげえ所に迷い込んじまったぞ、ゴルァ!
./ つ つ \______________________
〜(_⌒ヽ ドキドキ
)ノ `Jззз
0538nobodyさん
03/08/06 18:40ID:???悪いが、この程度も自力解決できないようだと、プログラミングは難しい。
試しに聞いてみるが、この程度のエラーが出る度に2chで何日もかけて尋ねるのか?
0539nobodyさん
03/08/06 18:43ID:???>>528みたいに、前の"の対応ができてない。
EOFにエラー出る場合は、大体括弧の対応がおかしい。
このくらいは覚えれ
0540nobodyさん
03/08/06 18:48ID:???そういう奴が以前いたな。
0541nobodyさん
03/08/06 18:50ID:???で動きません。どうしてですか?
0542nobodyさん
03/08/06 18:58ID:???>>1
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
0543nobodyさん
03/08/06 18:59ID:???Syntax errorがでました。
0544nobodyさん
03/08/06 19:07ID:???0546nobodyさん
03/08/06 20:05ID:???0548nobodyさん
03/08/06 20:59ID:???それと、
if(!iguzisuto "data.txtx"){処理;}
が動きません。
どうしてでしょうか。イグジストであってるはずなんですが・・・
0549nobodyさん
03/08/06 21:04ID:???o . 。 . . , . , o 。゚. ,゚ 。 + 。 。,゚.。
゚ , , 。 . + ゚ 。 。゚ . ゚。, ☆ * 。゚. o.゚ 。 . 。
。 . .。 o .. 。 ゚ ゚ , 。. o 。* 。 . o. 。 . .
。 . 。 . .゚o 。 *. 。 .. ☆ . +. . .
。 . . . . . 。 ゚。, ☆ ゚. + 。 ゚ ,。 . 。 , .。
゚ 。 ゚ . +。 ゚ * 。. , 。゚ +. 。*。 ゚. . . . .
。 . . 。 。゚. 。* 。, ´。. ☆。。. ゚。+ 。 .。 . 。 .
. 。 ゚ ゚。 。, .。o ☆ + ,゚。 *。. 。 。 . 。 .
゚ .゚ ゚ 。゚ + 。. +。 * 。゚。゚., ,+ 。゚. 。 . . , , .
゚。゚+゚`, o。。.゚*。゚ 。.゚ 。 ☆+。。゚. ° 。 . , ゚ ゚
。, .゚。 + ☆。,゚. o。 。+ 。゚., . ゚ , 。 。 . .
゚. o * 。゚。゚.。゚。+゚ 。 。 ゚。 ゚ 。 ゚
゚` .゚ .゚. ゚. . ゚ . ゚ . , . . . 。 ゚ .
. . . , 。 . . , .
。 ゚ . 。
, . . , . .
夏だね
。 V ∧∧ ∧∧ <うん。夏だ
( :;;;;;:::) ( :;;;;: )
. . /:;;;;;: | | :;;;:ヽ
〜(::;;;;;;:/. |:;;;;;;: )
‐''"´'''"""''"`''""`"""''''''"´'''"""''"`''""""'''"''''''"`"""''''``'‐
0550nobodyさん
03/08/06 21:05ID:???0551nobodyさん
03/08/06 21:24ID:???0552nobodyさん
03/08/06 21:27ID:ihwsdtLYはvalueを削除するがエントリーは残る、よって
$hash{'name'} = '';
と同じ。
undef $hash{'name'};
は未定義だからエントリーそのものがなくなる。
であってますか?
0553nobodyさん
03/08/06 21:54ID:???0557nobodyさん
03/08/06 22:20ID:???0559nobodyさん
03/08/07 07:46ID:???マニュアル *読めば* 理解できる事だが…
0560nobodyさん
03/08/07 10:17ID:MNjVgF7U$aの属性
$a = 100
$a1 = 200
$a2 = 300
$b
があるとする。このとき、$aの属性と$aの属性がぶつかったときは
なんともにないけど、$aの属性と$bの属性がぶつかったときは
条件が加えるようにしたい
それで
$aのときは条件をつけようと思ったんですけど、属性$aの定数が変数なので
条件がうまくつけられない
よい方法はないだろうか?
if = $a
だと下の2つが含まれなくなる。初心者だけど、わかりますか?
■ このスレッドは過去ログ倉庫に格納されています