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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2011/09/09(金) 18:11:49.71ID:???
Perlのコーディングで困ってる人のスレです。

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

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

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

お勧めサイトは >>2 以降

前スレ http://hibari.2ch.net/test/read.cgi/php/1295170172/
0043nobodyさん2011/09/19(月) 16:24:36.58ID:???
>>42
> この場合どうしたらいいんでしょうか・・・?
・管理者にインストールしてもらう
・設置先と同じ環境を手元にも構築してコンパイルしたものを持っていく
・設置先で利用できる形にまとめてくれている人を探して一式もらう
・Pure Perl なモジュールのみを使うよう書き換える
・サーバを替える

いずれにしてもスレ違い。
0044nobodyさん2011/09/19(月) 16:30:26.87ID:???
pure perlな実装で代用すれば良いんじゃね。
0045nobodyさん2011/09/19(月) 18:25:25.97ID:???
コンパイルもできるレンサバに替えるのがいいとおもふ。

#そして次は「すいません、できないと思ってたけどコンパイルできました」とか書き込まれそうな予感
0046nobodyさん2011/09/19(月) 20:13:19.63ID:tSer8QMI
すいません、できないと思ったけどコンパイル・・・という冗談は置いといて、
結局 XML::UserAgent も XML::Simple も使わずに済むPurePerlな XML::TreePP を使う事にしました。

こういう放置は本当はあまりよくないんでしょうけど、とりあえず完成させたいもので、とりあえず後で再考する事に。
失礼しました。
0047nobodyさん2011/09/19(月) 20:32:26.25ID:???
>>46
> こういう放置は本当はあまりよくないんでしょうけど、とりあえず完成させたいもので、とりあえず後で再考する事に。

いえいえ、良い選択だと思います。ご健闘を。
0048nobodyさん2011/09/19(月) 23:13:46.60ID:???
コンパイルができないと諦めるもんじゃない。
たとえshellが使えなくともtelnet.cgiみたいなのを使って
コンパイルすればいいのだ。

サーバーの環境を特定し、それに近い環境で
自宅コンパイルしたものをアップする方法もある。
諦める必要はないぞ!
0049nobodyさん2011/09/20(火) 00:23:18.16ID:VRYqCB7t
初心者です。2ちゃんの統計を出力するスクリプトを作りたくて、色んな場所からつぎはぎして作っていたのですが、問題がでて進めなくなりました。
板の中のスレの内容を表示しようというところまできたんですが、カウンターの i が動いていないような感じで、同じスレ(dat)が何回も表示されてしまいます。
ほかにもツッコミどころがあったら教えてください。
ソースは次のレスです。
0050nobodyさん2011/09/20(火) 00:24:28.62ID:VRYqCB7t
全部は入らないので関わってると思うところだけ抜きました。

use LWP::UserAgent;
use HTTP::Request::Common;

$url = "http://hidar.2ch.net/news4vip/subject.txt";
$durl = "http://hidari.2ch.net/news4vip/dat/";

&getData($url);

$threadlist = $response->content;

while($threadlist =~ m|\n(.*?)\.dat<>|g){
        push(@dat, $1);
        }

for ($i=0; $i<=$#dat; $i++){
        $url = $durl . $dat[i] . ".dat";
        &getData($url);
        $content .= $response->content . "\n";
}

print $content;

sub getData
{
        $ua = LWP::UserAgent->new;
        $ua->agent('');
        $request = GET($_[0]);
        $response = $ua->request($request);
}
0051nobodyさん2011/09/20(火) 00:41:47.24ID:VRYqCB7t
ごめんなさい、>>50です。
$url = "http://hidar.2ch.net/news4vip/subject.txt";
$durl = "http://hidari.2ch.net/news4vip/dat/";

はそれぞれ

$url = "http://hibari.2ch.net/news4vip/subject.txt";
$durl = "http://hibari.2ch.net/news4vip/dat/";

でした。別なURLでテストしてたのをごまかしたので、URLが間違っていたせいじゃないです。
ていうかdatディレクトリがそのまま見られるみたいだからそっちから抽出したほうがよかったかな・・・
0052nobodyさん2011/09/20(火) 00:41:59.51ID:???
>>50
コードはともかく、とりあえずiはミスタイプで正しくは$iだね
0053nobodyさん2011/09/20(火) 00:54:00.21ID:VRYqCB7t
>>52
できました!
ありがとうございます!!!
0054nobodyさん2011/09/20(火) 02:27:48.40ID:???
use strict;
use warnings;
この2つは必須!
0055nobodyさん2011/09/20(火) 21:27:29.45ID:P4zYemZJ
他のスレからこちらに誘導していただきましたのでここでも質問させていただきます。

初心者なのですが、どなたか教えてください。
サーバーに最新のapache(onWindowsXP)をインストールし、Activeperl(最新版)
によるcgiで、Win32::OLEをつかって、
サーバー側でAccess起動→マクロを走らせる→Access閉じる
を行いたいのですが、上手くいきません。
同じPERLソースで、AN HTTPD だと上手くいくので、apacheの設定の問題だと思うのですが、
どこをどう設定するのかが分かりません。

0056nobodyさん2011/09/20(火) 21:29:54.54ID:P4zYemZJ
つづきです。すみません。

ちなみにソースは
# Accesオブジェクトを生成、起動
my $access = CreateObject Win32::OLE 'Access.Application' || die "Cannot create Access object\n$!\n";
my $mdb = 'C:/hoge.mdb';
$access -> {'Visible'} = 1;
$access -> OpenCurrentDatabase($mdb);
$access -> DoCmd -> RunMacro('hoge');
$access-> quit();
undef $access;

です。

0057nobodyさん2011/09/20(火) 21:30:56.13ID:???
>>55-56
>>1
http://perldoc.jp/docs/perl/5.10.1/perlfaq9.pod
Apache〜嗜みとして〜 Part3
http://hibari.2ch.net/test/read.cgi/php/1043851302/
0058552011/09/20(火) 21:33:07.43ID:P4zYemZJ
つづきです。最後です。すみません。

現象としては、ログにもエラーはなく、サーバー側でタスクマネージャで確認すると
Accessが起動していることまでは確認できるのですが、そのまま止まってしまいます。
タスクマネージャーからAccessを強制終了すると、それ以後のperlスクリプトが処理されるようです。
どなたか同じようなご経験をお持ちの方はおられませんでしょうか。

宜しくお願い致します。
0059nobodyさん2011/09/20(火) 21:57:09.80ID:???
>>56
my $access = CreateObject Win32::OLE 'Access.Application' || die "Cannot create Access object\n$!\n";

my $access = Win32::OLE->CreateObject('Access.Application' || die "Cannot create Access object\n$!\n");
と等価なので CreateObject() が偽を返しても die しない。

http://perldoc.jp/docs/perl/5.14.1/perlop.pod#Operator32Precedence32and32Associativity

>>58
「それ以後」がどのステップを指していて処理自体は期待通りに終わっているのかどうか不明なので
同じ症状かは分からんが、「perl Win32::OLE access」でググれば

http://www.kaimei.org/read/internal/perl_w32
> 私が Win32::OLE から Excel へアクセスするプログラムを書いてみたところ、
> Perl スクリプトからだと問題ないのに CGI からこれを呼び出すと失敗するケースがあった。
> きちんとした原因まで把握できていないのだが、少なくともオープンする Excel ファイルのパスは
> / ではなく \ で区切らないとアプリケーション・オブジェクトの取得に失敗するようである。

という話が出てくる。
0060nobodyさん2011/09/21(水) 12:11:47.99ID:???
PSGI に対応した WAF では何が使い易いのでしょうか?
それぞれの WAF の特色とか違いとかが分かるサイトとかあるのでしょうか?
ご教示いただければと思います。
0061nobodyさん2011/09/21(水) 15:19:36.21ID:???
スレッドごとにファイルがあって
それをまとめるスレッドリストファイルがある場合のロックについて

ファイルロック1
スレッドNファイルへの書き込み
スレッドリストファイルへの書き込み
ファイルロック1の解除

というようにしなければならないので
例えばスレッド1にだれかが書き込んでいる最中は他スレッドでも書き込みができない
ということになる。
ということで間違いないんですか?

それとスレッドを誰かが見るだけの場合でも

ファイルロック1
スレッドNファイルの読み込み
スレッドリストファイルの読み込み
ファイルロック1の解除
としなければならないので

誰かが任意のスレッドを見ている間はどこのスレッドにも書き込めない

ということでいいんでしょうか?
そうするとロックかかりまくりじゃないんですか?
0062nobodyさん2011/09/21(水) 15:57:23.72ID:???
それぞれのファイルに対してロックすればいいだろ
0063nobodyさん2011/09/21(水) 16:36:39.63ID:???
>>62
それぞれのファイルにロックすると
スレッドNファイルには書き込まれて
スレッドリストファイルにロックがかかるという場合も考えられる
そうするとデータの連動がずれる
0064nobodyさん2011/09/21(水) 16:43:12.02ID:???
>>61
マルチスレッドプログラミング相談室 その8
http://hibari.2ch.net/test/read.cgi/tech/1253521167/
0065nobodyさん2011/09/21(水) 19:47:38.85ID:???
>>64
スレッドってそのスレッドじゃないと思うんだw
0066nobodyさん2011/09/21(水) 20:45:57.38ID:???
>>61
ロックかかりまくりとはいうけど
実際は各リクエストがケンカしないように順番に処理されていくわけだから特に問題はないだろ。
0067nobodyさん2011/09/21(水) 21:52:54.67ID:???
DBMSみたいに、まとめ役のプロセスが1つだけ起動して、もちろん複数起動しないようにして、
そいつが全部取り仕切るように動かせばいいんだ。疑似マルチタスクみたいに。
0068nobodyさん2011/09/22(木) 00:58:45.67ID:???
ロックには排他ロックと共有ロックがあってだな
・・という話ではない、これ?
0069nobodyさん2011/09/22(木) 01:17:49.95ID:???
シェケナベイベー
0070nobodyさん2011/09/22(木) 01:23:50.84ID:???
>>68
この件は全部排他
横からだけど>>61の解答は気になる
0071nobodyさん2011/09/22(木) 12:59:33.86ID:nJD1QeKS
教えてください
Perlで2chの特定のキーワードのスレを自動取得するCGIを改造したいのですが、

#板名「@BoadName」にある、スレッド名に「$KeyWord」を含む板の一覧を表示する。
$BoardName[0] = "大規模MMO";
$BoardName[1] = "ネトゲサロン";
$BoardName[2] = "ネットwatch";
$Keyword = "●○";

この条件のところで、大規模MMO板だけでなく、例えば
ニュー速等複数の板を指定するにはどういう風にコードを書き換えれば良いでしょうか?
なるべく簡単な方法を教えてください。

スクリプト
http://aceof.s57.xrea.com/?p=sp





0072nobodyさん2011/09/22(木) 13:11:19.13ID:???
>>71
正規表現を使えるようにすればいいんじゃないの。
0073712011/09/22(木) 13:39:16.30ID:nJD1QeKS
>>72
…?どうやるのでしょうか?
COBOLは昔習いましたが…
条件のところの
$BoardName[0] = "大規模MMO"; を
A(大規模MMO) AND B(ニュー速) のような条件にしたいのですが、
parlでの表記が分かりません。
コードを教えてください。



0074712011/09/22(木) 13:54:59.74ID:nJD1QeKS
例えば

$BoardName[0] = "大規模MMO" AND "涙目ニュース";

ではエラーになりますよね??

0075nobodyさん2011/09/22(木) 14:45:57.55ID:???
$BoardName[0] = "大規模MMO";
$BoardName[1] = "ネトゲサロン";
$BoardName[2] = "ネットwatch";

$BoardName[3] = "ニュース速報";
$BoardName[4] = "WebProg";

でいいんじゃないかな?
Socket って使ったことないからわかんないけど BoardName で追ってみると
http://www.ff.iij4u.or.jp/~ch2/bbsmenu.html
↑ここから $BoardName[n] でURL取ってるみたいだし
確認してないけど
0076712011/09/22(木) 15:29:52.18ID:nJD1QeKS
>>75
すみません、基本的に大きな勘違いをしていました

$BoardName[0] = "大規模MMO";  板名
$BoardName[1] = "ネトゲサロン"; スレット名
$BoardName[2] = "ネットwatch"; ?

かと思っていましたが、全部板名で、番号を増やしていけばいいだけですよね^^:

で、
$Keyword = "●○"; の所を2〜3個指定したいんですが、
複数指定したい場合はどう書けば良いのでしょうか?

$Keyword = "●○" "●▲" "××";

$Keyword = "●○" AND "●▲";
  でしょうか?
ANDの代替がぐぐっても分かりません・・・
ちなみにスレ一覧のURLは移動してましたので書き換えます。
0077nobodyさん2011/09/22(木) 15:44:33.61ID:???
>>71-76
【 スクリプト改造依頼スレ 】(丸投げ) part8
http://hibari.2ch.net/test/read.cgi/php/1314546533/
★三 【 スクリプト改造工房 PART 9 】 ★三
http://hibari.2ch.net/test/read.cgi/php/1143834740/
金出すから改造してよvol.3
http://hibari.2ch.net/test/read.cgi/php/1162147035/
0078712011/09/22(木) 16:01:22.71ID:nJD1QeKS
>>77
ありがとうございます。
あと、条件を複数指定する場合にどう記述すれば良いかだけ教えていただければ
十分なのですが…。
$Keyword = "●○" "●▲" "××";

$Keyword = "●○" AND "●▲";
  でしょうか?

それとも $Keyword = "●○","●▲";



0079nobodyさん2011/09/22(木) 16:13:15.01ID:???
うーん
COBOLをやってたというのがよく伝わってくる思考だw

$Keyword は GetData で

if (/$Keyword/){

というふうに正規表現で使われてるから論理演算子は使えないと思われ
$Keyword を @Keyword にしていっぱい入れられるようにして正規表現で | を使うか
if じゃない関数を使うかじゃないかな〜
0080nobodyさん2011/09/22(木) 18:12:10.54ID:5FtK50r8
読み込んで表示だけのページ=ロックの必要はない

読み込んだデータを更新して書き込むページ=
ファイルロック1
ファイル読み込みモードでオープン
ファイルを配列に読み込み
ファイルを閉じる

データ更新

ファイル書き込みモードでオープン
更新したデータをファイルに書き込む
ファイルを閉じる
ファイルロック1の解除

これでいいはず
仮に読み込んで表示だけのページを
ファイルロック1
ファイルを読み込みモードでオープン
データを配列に入れる
ファイルを閉じる
ファイルロック1の解除とすると
表示するだけのページを開く間は書き込みができなくなるから
そうすると書き込める隙がなかなかない
0081nobodyさん2011/09/22(木) 19:43:11.98ID:7t8BkGQU
use strict;
use warnings;

my @city = ("東京", "大阪", "名古屋");
delete($city[0]);
print "@city";

こんな簡単なので Use of unitialized value in join or string at *** line 6. っていう警告が出たんですが、どうしてですか?
それに Use of unitialized ... というエラーしょっちゅう見かけますが、調べてみてもよくわかりませんでした。
教えてくださいm(_ _)m
0082nobodyさん2011/09/22(木) 19:52:11.16ID:???
delete $city[0]; で undef になった $city[0] を print するのに使ったから

とりあえずexcite翻訳から初めてみたらどうでしょうか
0083nobodyさん2011/09/22(木) 20:01:45.61ID:???
>>81-82
http://perldoc.jp/docs/perl/5.10.0/perldiag.pod
0084nobodyさん2011/09/22(木) 20:15:05.37ID:7t8BkGQU
>>82-83
ありがとうごさいます。
@city = grep($_ ne "", @city);
で $city[0] を消しても残ってたので不便な関数だなと思いました。
undef の値を消すような操作をすればいいんですね。
0085nobodyさん2011/09/22(木) 20:16:16.72ID:???
つshift
0086nobodyさん2011/09/22(木) 21:48:02.28ID:???
$city[0] = "東京" を削除して詰めちゃってもいい ($city[0] = "大阪" とずれていい) なら
shift @city;
要素をずらさずに $city[0] だけ消したいなら
$city[0] = "";
0087nobodyさん2011/09/22(木) 21:53:14.20ID:???
あれ、$city[0] = undef;とdelete($city[0]);って同じ?
0088nobodyさん2011/09/22(木) 22:07:16.08ID:???
>>87
http://perldoc.jp/func/delete
http://perldoc.jp/func/undef
0089nobodyさん2011/09/22(木) 23:43:44.90ID:???
delete が非推奨とか・・・splice で削除しろとか書いてあるけどさ、
巨大な配列に対して splice すると、すごく遅そう・・・
0090nobodyさん2011/09/22(木) 23:56:59.38ID:???
>>89
Perl処理系のソースを見ずに言うが、
そのへんはパフォーマンスがガタ落ちにならん程度にはうまいこと処理してるだろうと思う。
0091nobodyさん2011/09/23(金) 00:35:13.51ID:???
ん?配列の要素に対する delete が非推奨なのは別に問題ないっしょ?
delete $array[$n] は要素を削除するのではなくて、むしろ undef $array[$n] に近いんだから。
0092nobodyさん2011/09/23(金) 00:37:24.81ID:???
spliceは引数多くて邪魔くさい
0093nobodyさん2011/09/23(金) 00:38:06.92ID:???
>>89
誤読すんなよ。

(特殊挙動の切り詰めの事を想定してるなら別だが)
splice で対処しろってのは、要素を本当に削除するケースに関してだ。
@arr = 1 .. 5 ; => @arr = qw( 1 2 5 );

delete の代りなら、
splice @arr, 2, 2, (undef) x 2 なんてしなくても
@arr[2,3] = (undef)x2 ;なりの方法があろう。
0094nobodyさん2011/09/23(金) 01:21:24.31ID:???
8万の配列に長さ1の文字列を入れて、delete、undef、spliceでベンチマーク取ったけど、
spliceが一番遅かったけど大きな速度差は出なかった
0095nobodyさん2011/09/23(金) 01:24:44.39ID:???
>>94
あと1つか2つ桁増やしてよろしく。
0096nobodyさん2011/09/23(金) 07:44:14.40ID:???
use Benchmark qw( timethese cmpthese ) ;
cmpthese timethese ( undef, {
delete => sub{ my @arr = ARRAY ; delete @arr[ 99999 .. 999999] },
splice => sub{ my @arr = ARRAY ; splice @arr, 99999, 900000, (undef) x 900000 },
slice => sub{ my @arr = ARRAY ; @arr[99999 .. 999999] = (undef) x 900000 }
});
__DATA__
ARRAY => (q{x}) x 1000000
Benchmark: running delete, slice, splice for at least 3 CPU seconds...
delete: 3 wallclock secs ( 2.91 usr + 0.15 sys = 3.06 CPU) @ 2.94/s (n=9)
slice: 4 wallclock secs ( 3.17 usr + 0.14 sys = 3.31 CPU) @ 2.72/s (n=9)
splice: 3 wallclock secs ( 3.06 usr + 0.19 sys = 3.25 CPU) @ 3.08/s (n=10)
Rate slice delete splice
slice 2.72/s -- -8% -12%
delete 2.94/s 8% -- -4%
splice 3.08/s 13% 5% --

ARRAY => 1 .. 1000000
Benchmark: running delete, slice, splice for at least 3 CPU seconds...
delete: 3 wallclock secs ( 3.12 usr + 0.00 sys = 3.12 CPU) @ 12.82/s (n=40)
slice: 3 wallclock secs ( 3.02 usr + 0.01 sys = 3.03 CPU) @ 6.93/s (n=21)
splice: 3 wallclock secs ( 3.03 usr + 0.07 sys = 3.10 CPU) @ 9.35/s (n=29)
Rate slice splice delete
slice 6.93/s -- -26% -46%
splice 9.35/s 35% -- -27%
delete 12.8/s 85% 37% --
0097nobodyさん2011/09/24(土) 11:44:49.89ID:???
文字コードで分からないことがあるのでご教授お願いいたします。
(utf-8 でソースを書いています)


utf-8 の半角ア -> EFBDB1
utf-16 の半角ア -> FF71

utf-8 でソースを書いているのだから、print "0xEFBDB1" で半角アが出力されるだろうと思ったら、
print "0xFF71" でないと半角アが表示されませんでした。
0098nobodyさん2011/09/24(土) 16:12:39.72ID:???
cryptって絶対に復号化できないんですか?
パスワードをこの関数を使って暗号しようと思っていますが
この関数を使う上で欠点や注意点がありましたら教えてもらえませんか?
0099nobodyさん2011/09/24(土) 16:30:15.23ID:???
>>98
>>1
http://perldoc.jp/func/crypt
0100nobodyさん2011/09/24(土) 16:48:02.74ID:???
>>97
半角のイなら、0xFF72です。
0101nobodyさん2011/09/24(土) 18:00:52.20ID:???
>>97
0xは数値に対してなので、\xだと思いますが、\xは2桁までしか拾わないので、
3桁以上の場合は、{ }を使って\x{123}とする必要があります。

2桁の場合は(\x{00B1}としても2桁と解釈されます)、その値そのもののバイナリ
文字列となります。

print "\xEF\xBD\xB1";

これ↑は、UTF-8として解釈すれば「ア」を意味するバイナリ文字列です。
ただし、Perlがこれを文字列処理するときはISO 8859-1という文字コードの3文字
として扱います。

3桁以上の場合は、その値のUnicodeコードポイント(U+FF71)のテキスト文字列となります。
( Perlは、"\x{FF71}"を「ア」という1文字として扱う)

バイナリ文字列(=バイト文字列)とは、バイト単位で処理される文字列のことです。
テキスト文字列とは、文字単位で処理される文字列のことです。
0102nobodyさん2011/09/24(土) 18:01:21.98ID:???
>>99
リンクありがとう〜 とりあえずこれ使ってみることにします
0103nobodyさん2011/09/24(土) 19:43:27.75ID:???
>>101
ありがとうございます!
0104nobodyさん2011/09/26(月) 12:35:58.38ID:???
トリップを生成する仕組みなんですが、

if (length $handle_pass >= 12)
{
my $mark = substr($handle_pass, 0, 1);
if ($mark eq '#' || $mark eq '$')
{
if ($handle_pass =~ m|^#([[:xdigit:]]{16})([./0-9A-Za-z]{0,2})$|)
{
$GB->{TRIPSTRING} = substr(crypt(pack('H*', $1), "$2.."), -10);
}

文字列12バイト以上で、先頭が#または$の場合、
$handle_pass =~ m|^#([[:xdigit:]]{16})([./0-9A-Za-z]{0,2})$|を行なって
cryptによって生成していると思います。

しかし、$GB->{TRIPSTRING}や$1や$2をprintすると何も表示されません。
$handle_pass =~ m|^#([[:xdigit:]]{16})([./0-9A-Za-z]{0,2})$|では何を行なっているのですか?
教えてください。
0105nobodyさん2011/09/26(月) 12:55:07.21ID:???
>>104
関係ないけど、これ $ から始まる場合何もしてないよね
0106 ◆??? 2011/09/26(月) 13:01:10.88ID:???
>>104
##0123456789abcdefxx 形式のトリップキーかどうかのチェックだろ

>>105
>>104は書いてないけど実際はelseがある
2chでは今のところ単に予約としてとってあるだけらしいから???になるだけだけど
01071042011/09/26(月) 14:03:37.14ID:???
>>105-106
ご回答ありがとうございます。
もう一度正規表現を調べますので、
その後、質問させてください。
01081042011/09/26(月) 17:00:08.24ID:???
先頭が#で始まり16進数文字が16個連続し、
末尾は./0-9A-Za-zのいずれかが0個以上2個以下連続する。

ですよね?

#0123456789abcdefxxは真
#0123456789abcdefxxxは偽
#0123456789abcdefは真

#0123456789abcdefあ が偽なのは、なぜでしょうか?

また、[[:xdigit:]]の[]が二重でくくられている意味を教えてください。
01091042011/09/26(月) 17:01:58.51ID:???
すみません、書きこんで気づきましたが、

#0123456789abcdefも偽ではないのか?と思います。
0110nobodyさん2011/09/26(月) 18:06:25.07ID:???
あ は [a-zA-Z0-9] かどうか
f の後ろに続く判断が ? なのか + なのかで意味合いが変わってくるかと。

トリップキーの規格をもっかい調べてみればよいかと。
0111nobodyさん2011/09/27(火) 00:54:20.16ID:???
ファイルのロックはmkdirなどでロック用ディレクトリ
を作る方法は良く見かけますがディレクトリではなく
openでロック用ファイルを作るというのは問題があるんでしょうか?
0112nobodyさん2011/09/27(火) 01:02:44.10ID:???
rename とか mkdir はシステムコールを使ってるから、open より割り込まれる余地が少ない。

とかじゃなかったっけ?
0113nobodyさん2011/09/27(火) 01:31:29.84ID:???
>>111
http://www.din.or.jp/~ohzaki/perl.htm#File_Lock

今時 flock を使えない環境に出くわす事も稀だがな。
http://perldoc.perl.org/perlport.html#flock
0114nobodyさん2011/09/27(火) 02:07:22.29ID:???
モジュールを作ってて、そのモジュールの中では use utf8 とか、open(my $in, '<:utf8', '〜') とかしてます。

しかし use utf8 してないスクリプトから呼ばれた時には、これだと文字化けが起きてしまいます。
そのため use utf8 されていない場合にはフラグを落として返したいのですが、
モジュールを呼んだスクリプトで use utf8 されてるかどうか調べる方法はあるのでしょうか?


モジュールが特定の文字コードに依存すること自体が駄目だとは分かっては居るのですが・・・
0115nobodyさん2011/09/27(火) 04:57:52.69ID:???
>>112
余地が少ないんじゃなくて余地が無い、
つまり処理がアトミックでないとだめなんだよ。
「余地が少ない」んじゃ意味ないの。
0116nobodyさん2011/09/27(火) 11:02:16.14ID:???
flock(XX, 2)
でデッドロックが発生した場合はどうなるんでしょうか?
あと、待ってる間は自動でsleepしてくれるんでしょうか?

flock(XX, 6)
で自分で実装するのとどちらが良いのか迷ってます。
0117nobodyさん2011/09/27(火) 19:02:14.19ID:???
すいません。プログラムを定刻になると自動で実行するようにしたいんですが、できますか?
レンタルサーバに置きます。
全体を無限ループをしてsleep()で休むというのを考えたのですが、無限ループは一番やってはいけないらしいですね。

あと検索するとすぐJavaScriptで自動更新する方法が出てきますが、
この方法だと時限以外にもCGIにアクセスされたときに実行してしまうと思います。
JavaScriptだけに実行させたいときはパーミッションをどう設定すればいいですか?
0118nobodyさん2011/09/27(火) 19:46:39.67ID:???
>>116
>明白ではないものの、伝統的な flock の動作としては、ロックが得られるまで 無限に待ち続けるものと、単に勧告的に ロックするものの二つがあります。

>>117
cronのことを聞いてる?
0119nobodyさん2011/09/27(火) 21:07:32.00ID:???
>>118
その説明を読んで具体的にどうなるのかが分からなかった
伝統的とか無限とか

・複数のプロセスが待ち状態になった場合に、次にロックを得られる順番は?
・デッドロックかかったらプロセスはどうなるのか
・待ってる間の負荷は

この辺りが気になる。
0120nobodyさん2011/09/27(火) 22:48:37.67ID:???
・複数のプロセスが待ち状態になった場合に、次にロックを得られる順番は?
システムにしか分かりません

・デッドロックかかったらプロセスはどうなるのか
flock を待つオプションで呼び、他のプロセスが死ねばロックは外れるので先に進めますが、
mod_perlなどではプロセスは死なないのでflockは掛かったままになります。
なので、flockを呼ぶときは待たないようにしましょう
0121nobodyさん2011/09/27(火) 23:25:00.27ID:???
flock呼んだ順番になるのか、ランダムになるのかの2択くらいかと思ったんですが、後者って認識でいいです?

無限に待ち続けるとあるんですが、待たないようにする方法もあるんでしょうか?

あと、大量のプロセスが待ち状態になった場合の負荷も気になります。
大人しく待ってるんでしょうか?
0122nobodyさん2011/09/27(火) 23:54:57.99ID:???
unlock時に起き上がったプロセスがロックを取れる
LOCK_NBだ、ドキュメントぐらい読め
sleep以外に何をするのか、それ以前にロック待ちが大量にある時点でどうか
0123nobodyさん2011/09/28(水) 01:15:39.74ID:???
>>117
>>118 の書いているとおり通常はcronを使う。と思う。

> あと検索するとすぐJavaScriptで自動更新する方法が出てきますが、

「プログラムを定刻になると自動で実行」させるのにJavaScriptをどうやって使うの? 意味がわからん。

> JavaScriptだけに実行させたいときはパーミッションをどう設定すればいいですか?

さらに意味がわからん。
0124nobodyさん2011/09/28(水) 01:29:17.95ID:???
>>123
俺は最初、サーバサイドでjavascriptを動かすnode.jsのこと言ってるのかと思った。
cronを扱うためのapiもあるみたいだし。
perl関係ないけど。
0125nobodyさん2011/09/28(水) 02:00:23.29ID:???
>>122
ありがとうございました。
LOCK_NB使わずに待たない方法があると勘違いしてました。
素直に自分で実装します。
0126nobodyさん2011/09/28(水) 13:39:10.69ID:???
ファイルの読み書きでトランザクションを実現するモジュールを apache が標準で持ってくれるとありがたい
0127nobodyさん2011/09/28(水) 17:26:59.68ID:???
ファイルの読み込みは@lines = <IN>で一括して配列に入れていますが
while<IN>で1行ずつ読み込む方がいいんですか?
配列を引数にしたり戻り値にしたりする場合が多いから
どうしても一括読み込みが多くなってしまいますが
一括読み込みだとそんなにメモリの負担になりますか?

ていうか<IN>自体にもファイル全部のデータが格納されているんですよね?
0128nobodyさん2011/09/28(水) 18:31:25.70ID:???
GB単位でファイルを処理する人間だと、while で回すなりの工夫は必要だけど、
今のご時世だったら、殆どの人は気にする事は無いでしょ。

>ていうか<IN>自体にもファイル全部のデータが格納されているんですよね?
そんなスーパーな挙動を取られたら、5GBファイルを 2GB メモリの PC で解析
出来ないじゃないですかっ
0129nobodyさん2011/09/28(水) 21:17:17.61ID:???
一行づつ読み込んだら遅くなる。
0130nobodyさん2011/09/28(水) 22:32:03.45ID:???
% perl -le '$s = q{x} x 1000000 ; $s =~ s/(.{1,50})/$1\n/g; print $s ' > test.txt
% cat hoge.pl
use Benchmark qw( timethese cmpthese ) ;
cmpthese timethese ( undef, {
arr => sub { open my $fh, q{<}, q{test.txt} ; my @arr = <$fh> ; close $fh ; @arr },
whi => sub { open my $fh, q{<}, q{test.txt} ; my @arr ; while (<$fh>){ push @arr, $_ } close $fh ; @arr },
aho => sub { open my $fh, q{<}, q{test.txt} ; my @arr ; for (<$fh>){ push @arr, $_ } close $fh ; @arr },
});
% perl hoge.pl
Benchmark: running aho, arr, whi for at least 3 CPU seconds...
aho: 3 wallclock secs ( 2.76 usr + 0.35 sys = 3.11 CPU) @ 48.87/s (n=152)
arr: 3 wallclock secs ( 2.72 usr + 0.41 sys = 3.13 CPU) @ 56.55/s (n=177)
whi: 3 wallclock secs ( 2.85 usr + 0.30 sys = 3.15 CPU) @ 70.79/s (n=223)
Rate aho arr whi
aho 48.9/s -- -14% -31%
arr 56.5/s 16% -- -20%
whi 70.8/s 45% 25% --
0131nobodyさん2011/09/28(水) 22:55:36.32ID:???
>>130
コメントは大事だよー
whileが一番速いのか 理由は何なんだろうな
0132nobodyさん2011/09/28(水) 23:04:50.68ID:???
whileでファイルの2行目から読み込むのってどうやるんですか?
0133nobodyさん2011/09/29(木) 00:01:53.09ID:???
<FH>;
while (<FH>) {
}
0134nobodyさん2011/09/29(木) 00:44:49.60ID:???
>>131
ファイルがメモリにキャッシュされたから。
最後に書いたほうが早くなる。
0135nobodyさん2011/09/29(木) 00:45:39.00ID:???
訂正
最後に処理されたもののほうが早くなる。
0136nobodyさん2011/09/29(木) 00:54:10.24ID:???
最後も何も2回目以降同じじゃね
仮にキャッシュされてるんなら
0137nobodyさん2011/09/29(木) 01:02:01.08ID:???
>>135
適当に順番入れ替えてやってみ。
結果はほとんど変わらないから。

ていうかよく見たら一番最後に処理したahoが一番遅いじゃねーか。
0138nobodyさん2011/09/29(木) 01:09:34.61ID:???
やっぱり一度に全部読んだほうが2倍以上速かったな。

all => sub { open my $fh, '<', 'test.txt'; my $buf; read($fh, $buf, (-s 'test.txt')); close $fh ; return split("\n", $buf);},
0139nobodyさん2011/09/29(木) 01:35:54.32ID:???
一度に全部読んだほうが処理がしやすい場合が多い

ファイルの下に行くほど新しい書き込みの場合
最新のn件を表示する場合はwhileで1行ずつは難しいな
@linesに全部読み込んで@linesの配列の後ろからn番までを切り取って表示すれば簡単だな
0140nobodyさん2011/09/29(木) 01:40:46.41ID:???
結局のところ「用途による」だろ
0141nobodyさん2011/09/29(木) 01:53:22.20ID:???
>>139
ファイルの最後の方から読んでいって
改行の数を数えたほうが早いよ。
0142nobodyさん2011/09/29(木) 02:22:14.02ID:???
ファイルの最後の行から上の行に向かって1行ずつ取り出せるの?
ファイル読み込み位置操作できるのseekしか見つからなかったが
これ行単位じゃなく後ろからのバイト数なんだよな
■ このスレッドは過去ログ倉庫に格納されています