Perlコーディング初心者質問スレ Part 61
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2010/06/05(土) 21:11:10ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >2 以降
前スレ http://pc11.2ch.net/test/read.cgi/php/1251989472/
0722nobodyさん
2010/11/24(水) 21:13:49ID:???書こうとした事を先に書かれた orz
「まとめ役が居ないから」
これに限る。
全てのファイル操作を一手に引き受ける Apache モジュールを作って、
全ての CGI/モジュールは ファイル操作を受け持つ Apache モジュール経由で
操作すれば OK
そうすれば DB を使わないスクリプトとかでも完全なファイルロックが可能。
そのモジュールにバグが無ければだけどw
0723nobodyさん
2010/11/24(水) 22:54:58ID:???> while(!do{ open my $fh,">",$flagfile; close $fh; }) {}
このopenて、毎回必ず成功するか毎回必ず失敗するか、しかないよ。たぶん。
必ず失敗するとしたらファイルのパーミッションで弾かれるとかくらい。(他にもあるかな?)
だからwhileで「closeが成功するまで繰り返す」てのは意味ない。
まあ仮にこれで「ファイル使用中ですよ」宣言ができたとして、
前者のプロセスと後者のプロセス、それぞれ同時に1つのプロセスしか起動しないとしても
タイミングによってはまったく排他処理できない。
上のプロセスをA、下のプロセスをB、としてそれぞれ行番号つけてみる。
A1: my $flagfile="locked";
A2: while(!do{ open my $fh,">",$flagfile; close $fh; }) {}
A3: # ファイル処理
A4: unlink $locked;
B1: my $flagfile="locked";
B2: while (-e $flagfile) {}
B3: # ファイル処理
(続く)
0724nobodyさん
2010/11/24(水) 22:56:39ID:???AのプロセスとBのプロセスは同時に任意のタイミングで動作するわけだから、
もしも次のような順番で処理が進むと…
B1: my $flagfile="locked";
A1: my $flagfile="locked";
B2: while (-e $flagfile) {}
A2: while(!do{ open my $fh,">",$flagfile; close $fh; }) {}
B3: # ファイル処理
A3: # ファイル処理
A4: unlink $locked;
B2の段階でA2のロックはかかってないので、プロセスBは次にB3の処理に入る。
その直前にプロセスAがA2でロックをかけても、プロセスBはそれに気づかない。
で、プロセスAのファイル処理(A3)とプロセスBのファイル処理(B3)が同時に(交互に)走って、
結果がわやくちゃになる、と。
どのプロセスも、自分以外のプロセスがロックをかけてないかチェックする必要があるし、
自分のプロセスが使用中なことを他のプロセスに知らせる(ロックをかける)必要がある。
そして、その時に上の方にでてきた「atmic」な処理が必要になるんだな。
つまり、ロックをチェックする処理とロックをかける処理を、OSのマルチタスク処理で
細切れにされないようにまとめて(一気に)やらないといけない。
それが可能な手段はflockやsymlinkやmkdirや、sysopenのO_EXLOCKなど、限られている。
という訳で >>721 のsleepかます処理は全く意味がないんだった。
0725nobodyさん
2010/11/24(水) 23:50:30ID:???Windows用のPerl5.8で確認してみたけどsleep(1)をそれぞれのwhile文の後に
かますとちゃんと動作するようだよ
確認してみた?
0726nobodyさん
2010/11/25(木) 00:19:03ID:???sleepかまさなくても不都合なく動作する時は動作するし
(ていうかプロセス数が少なく処理のタイミングがまばらなら大抵の場合は問題ないだろう)
sleepかましてもカチ合ってうまくいかない時はうまくいかない。
それだけのことでしょ。
逆になんでsleepかますとうまく動くのか説明してくれ。
0727nobodyさん
2010/11/25(木) 00:27:18ID:???と思ったけど?
0728nobodyさん
2010/11/25(木) 00:30:56ID:???最初たまたまうまくいくことがあるが、すぐにどちらかのプロセスがアクセス権を独占する
0729nobodyさん
2010/11/25(木) 00:52:31ID:???そりゃたぶんどちらかじゃなくて上の方のプロセスがいつも独占するんだろう。
おそらくそれぞれの処理をwaitを置かずに無限ループ内でひたすら繰り返すような検証スクリプトを書いたんじゃないの。
1秒もsleep入ってるんだから、それぞれ処理時間が1秒以内に完了する程度の量なら、
うまく相互の起動のタイミングが合えば延々走り続けるだろうな。
ただループを回る時間に両者で少しでも差があれば、
いつかは上の方のプロセスが処理を独占するようになる。
ループ1回につき1秒ずつ遅延があるから、そうなるまでだいぶ待たないといけんだろうけど。
0730nobodyさん
2010/11/25(木) 01:02:48ID:???いや、正確に言うとごく短時間のウエイト処理を置いた
その処理時間ではアクセス権を譲渡しきれなかった
というか、要するにウエイト時間を長くしていけばうまくいくという理解でいいのかな?
もう、これ以上この件に関わるの疲れてきたんだけど・・・
0731nobodyさん
2010/11/25(木) 01:11:03ID:???> というか、要するにウエイト時間を長くしていけばうまくいくという理解でいいのかな?
違う。ちゃんと排他制御をしないと結局のところ解決はしない。
ウェイト(sleep時間)を長くすればするほど、カチ合う確率は低くなるだろうけど、
確率が低くなるだけでカチ合わなくなる訳ではないのだ。
まあ「1秒」ってコンピュータの処理速度からしたらものすごーく長い時間だけどさ。
> もう、これ以上この件に関わるの疲れてきたんだけど・・・
おつかれさま。おやすみ。気が向いたら排他制御の仕組みをきちんと勉強してみてね。
0732nobodyさん
2010/11/25(木) 01:14:16ID:???追伸。「sleepを入れることでアクセス権の譲渡が間に合うようになる」という解釈は間違っているので、念のため。
0733nobodyさん
2010/11/25(木) 01:17:43ID:???0734nobodyさん
2010/11/25(木) 02:05:15ID:???>>705
Vはいいとして、
Cが遷移とかWeb関係、
MがWebじゃなくても使いまわせるロジック
乱暴だけど、MにORMだとかDBだとかを単純に対応付けるよりかはマシな説明だと思う。
0735676
2010/11/25(木) 09:57:28ID:???コード晒してみて良いでしょうか。
細かい点はさておいて、MVC的に合ってるのか確認したいのです。
肝心のモジュールの中身が一番いい加減だとは思うのですが・・・
改行数の都合上、色々と端折ります。
use CGI;
use My::Module; # My::Definitionを継承、ret_xxxxメソッドが該当
use My::Session;
my $session = My::Session->new();
my $sess = $session->chk_session; # if session expired, return undef.
if (!$sess) {
$session->loginForm;
} elsif ($sess) {
my $q = CGI->new();
my $param1 = $q->param('param1');
my $mod = My::Module->new();
my $tx = $mod->ret_Xslate;
my $dbh = $mod->ret_DBI;
if (!$param1) {
my $contents = $tx->render( 中略 );
print $contents;
} else {
# 大きく中略。$returnを取得するSQL文を書いてる。
my $contents = $tx->render("hoge.tmpl", {
title => "fuga",
value => $return;
});
print $contents;
}
}
0736nobodyさん
2010/11/25(木) 21:42:32ID:???0737nobodyさん
2010/11/25(木) 23:00:23ID:???0738nobodyさん
2010/11/26(金) 00:07:31ID:???># 大きく中略。$returnを取得するSQL文を書いてる。
例えばこの$returnは仮に foo($param1) という呼び出しで取れるとして、
$param1がフォームからの入力値である必要は無く
コマンドラインから呼び出して foo($ARGV[0]) としても正しく動くわけで、
foo()はコントローラには無くてもいいよね。
#そう切り分けることを>705でモジュールと呼んでたのなら近い認識かも知れない
余計なお世話だけど if(!$param1) だと $param1 に "0" が入った時も真判定されるので
if ($param1 ne "") という意図ならそのように書いた方がいいよ。
0739nobodyさん
2010/11/26(金) 01:03:21ID:???param('param1') は、param1というパラメータ自体が無かった場合はundefを返し、パラメータはあるが値が無かった場合は空文字列になる。
だから ne "" は正しくなく、「動く」のを優先するなら735のままで実は正しい。ただしたまたま動いているだけなので、ちゃんと書くならdefinedを使う。
if (not defined $param1)
あと$param1がundefだった場合に ne を使うとuninitializedのwarnが出る。
0740nobodyさん
2010/11/26(金) 02:02:18ID:???0741676
2010/11/26(金) 03:18:48ID:???>>705はM - モジュールというより、M - モジュール化という方が近かったですね。
ちなみに、今現在$returnを取得するのは、各スクリプト内固有のSQLなので、
スクリプト間でSQLに重複があれば、モジュールに放り込もうとは思っています。
>>738-739
実はここ、
> my $sess = $session->chk_session; # if session expired, return undef.
の、「return undef.」はウソで、実際には1 or 0を返しています。
if ( not defined $sess )とすると、全てのセッションが通る・・・
param1のケースを考えると、
× return 0;
○ return undef; # or return;のみ
とした方が良さそうですね。
色々とありがとうございました。
0742nobodyさん
2010/11/26(金) 16:52:51ID:???>$ua = LWP::UserAgent->new;
0743Perl忍者 ◆M5ZWRnXOj6
2010/11/26(金) 17:17:16ID:pwS23Ki10746nobodyさん
2010/11/26(金) 17:45:18ID:???自作のショッピングカートプログラムにクレジットカード決済機能をつけたい。
その為には、決済代行業者のプログラムに接続しなきゃならない。
できるか?
0749nobodyさん
2010/11/26(金) 18:31:10ID:???my $ua = LWP::UserAgent->new;
って同じなん?
0750nobodyさん
2010/11/26(金) 19:50:57ID:???俺だよオレ俺
0751nobodyさん
2010/11/26(金) 20:12:08ID:???必ずしも決まった形ではないようだね。
0752nobodyさん
2010/11/26(金) 20:35:45ID:???曖昧さがあってときどき期待しない解釈をされてわかりにくい
バグの元だから矢印だけを使う方がいいとperlobj(1)に書いて
あるよ。
0753nobodyさん
2010/11/26(金) 21:21:45ID:???0754Perl忍者 ◆M5ZWRnXOj6
2010/11/26(金) 21:49:28ID:pwS23Ki1あと外部プログラムにつないだりできるよ
0755Perl忍者 ◆M5ZWRnXOj6
2010/11/26(金) 21:52:42ID:pwS23Ki1オブジェクトの理解でつまってるってほんと終わってるねw
0756nobodyさん
2010/11/26(金) 22:57:56ID:???は
my $ua = LWP::UserAgent->new;
のシンタックスシュガー、だっけ?
0757nobodyさん
2010/11/26(金) 23:30:39ID:???0758nobodyさん
2010/11/26(金) 23:47:19ID:???print $fh
0760nobodyさん
2010/11/27(土) 03:55:49ID:???0761nobodyさん
2010/11/27(土) 04:38:13ID:???「とあるPerlの糖衣構文(シンタックスシュガー)」
思ったよりつまらんな
0763なるとくん
2010/11/27(土) 19:43:14ID:40qrjSo/0765nobodyさん
2010/11/28(日) 00:44:24ID:???0767nobodyさん
2010/11/29(月) 05:53:06ID:???@list = (a,b,c,……);
$length = @list;
<script language="javascript">
for(i = 0; i<$length; i++){
…
#このfor文の中で
# $list[i] を使うとエラーになり、
# "$list[i]"だと参照できますがインデックスのiがインクリメントせず最初の要素aが繰り返し参照されます。インクリメントしてほしいです
…
}
どうしたらいいでしょうか?
0768nobodyさん
2010/11/29(月) 06:20:49ID:???0769nobodyさん
2010/11/29(月) 06:32:34ID:???perl側の配列を使いたい、ということ?
でもperlで作った配列はJavaScriptからは当然見えっこないんだから
JavaScript側にもperlの@listと同じデータ列の配列を定義しておいてやらねばいけないんでは
### perlコード
my @list = (1, 2, 3);
# @list = (a, b, c) は変じゃないか? ("a", "b", "c") ならわかるけど…
my $js_array = join ', ', @list;
# @listの内容が文字・文字列の場合はこうかなちょっと冗長だけど
# my $js_array = join ', ', map "'" . $_ . "'", @list;
### JavaScriptコード
print <<EOT;
<script type="text/javascript">
list = new Array($js_array);
for (i = 0; i < list.length; i++) {
document.write(list[i]);
}
</script>
EOT
それとも JavaScript のループ内で、JavaScriptの配列の添字 (i) を使って
Perl の側の配列 (@list) の要素を取り出したいということ?
しかしその場合そもそもJavaScriptのコード側がforループになっている必要あるの?
Perl側の段階でforeach等でループ処理するべきなんでは
0770767
2010/11/29(月) 07:16:51ID:???中身も書くべきでしたね
すみません
>>769
joinでまとめて変数に入れれば良かったのですね
配列として使いたかったので助かりました
ありがとうございます
0771676
2010/11/29(月) 13:13:48ID:???BはCに戻る方が正しいかもしれませんが・・・
http://ichigo-up.com/cgi/up/qqq/nm28196.png
0772nobodyさん
2010/11/30(火) 00:10:19ID:???以下の方法でreadしても、何も入っていません。
if ($ENV{REQUEST_METHOD} eq 'POST') {
read(STDIN, $read_data, $ENV{'CONTENT_LENGTH'});
}
別ページへPOSTした場合は、受け取ることができたのですが…
CGI.pmが使えない環境で、別に何か方法はありますか?
0773nobodyさん
2010/11/30(火) 00:20:25ID:???0774nobodyさん
2010/11/30(火) 01:23:19ID:???何故か強力なキャッシュが働いてるか・・・
なんとも言えん
0776772
2010/12/01(水) 01:26:55ID:???...
read(STDIN, $read_data, $ENV{'CONTENT_LENGTH'});
と書いてたのがreadが空だった原因みたいです。
my $read_data;に修正したらreadできるようになりました。
または、readを削って、my $read_data = <>;だけでも読めました。
ダイアモンド演算子を訳もわからず使ってました。
0778nobodyさん
2010/12/01(水) 02:23:15ID:???ここを参考にやってんだけど、データベースに接続できないorz@MySQL 5.1.41
DBD は CPAN じゃなくて ppm で拾ってきたものを使用
0779nobodyさん
2010/12/01(水) 02:31:06ID:???show grant for tester@localhost;
GRANT ALL PRIVILEGES ON *.* TO 'tester'@'localhost' IDENTIFIED BY PASSWORD '*****'
GRANT ALL PRIVILEGES ON `testdb`.* TO 'tester'@'localhost'
perl から connect('DBI:mysql:testdb:localhost' , $username, $password); ってすると、
Can't connect to MySQL server on 'localhost' (10061)
ってなる。
むぅ。。。
0782nobodyさん
2010/12/01(水) 23:41:40ID:???print <<EOF;
<?PHP
print "Content-type: text/html\n";
$G='0';
if($G==1){$G3=1;}
else if($G==2){$G3=2}
?>
EOF
こうしてみたらContent-type: text/htmlだけがテキスト出力されるのだけどどうしたらいいのかな?
0783nobodyさん
2010/12/01(水) 23:59:03ID:???これはPerlとPHPのコードが混じってるの?
どういう動きを期待してるのか分からない。
もしPerlスクリプトの一部分を新規のPHPプロセスで呼び出そうとしてるとか
Perlの出力結果をPHPソースコードとして見て改めてPHPで実行する(またはその逆)とか
そういう事なら余計重くなるだろうね。
PHPスクリプトを動的に作ってドキュメントルート以下にphpファイルとして書き出すなら分からなくもないけど。
0784nobodyさん
2010/12/02(木) 00:38:59ID:???Content-type: text/html\n\n
を出力するのはperl(CGIスクリプト)側の仕事だろう。
で、PHPコード中でいじってる$Gや$G3はどこで使ってるの?
Perlスクリプトで参照してるんだったら全く意味がない。
あとPHPでelse ifを書く時はの表記は「elseif」。
0785nobodyさん
2010/12/02(木) 00:56:20ID:???0786nobodyさん
2010/12/02(木) 01:01:43ID:???まあなんにしても何がやりたいのかまったくわからんわけだが
0787nobodyさん
2010/12/02(木) 03:03:55ID:???CGIが走ってる最中にPHP文書いたからってモジュールモードで動くのか?
・・・仮にそうだとしてもifひとつで差が出るとは思えんが
というか逆に遅くなりそうだが
0788nobodyさん
2010/12/02(木) 04:23:37ID:???となるとContent-type: text/htmlが表示されたっていうのはどういうことなんだ?
0789nobodyさん
2010/12/02(木) 06:58:59ID:???0790nobodyさん
2010/12/02(木) 11:22:29ID:???$w = 0;
$h = 0;
$t = 0;
@we = ();
@he = ();
@tr = ();
for($i = 0;$i <= 6;$i++){
if(${'item'.$i}[1] = 0){
$we[$w] = "@{'item'.$i}";
$w++;
}
elsif(${'item'.$i}[1] = 1){
$he[$h] = "@{'item'.$i}";
$h++;
}
else{
$tr[$t] = "@{'item'.$i}";
$t++;
}
}
item.txtには各行に @item(数字) = ("文字列",0〜2の数字,0〜2の数字); の配列が入っています
2つ目の数字の要素で各配列を3つの配列@we,@he,@trに振り分けたいのですが、要素の数字によらず全て@heに入ってしまいます
文字列の要素のせいでif文のイコールがブール値を求めているのか、(${'item'.$i}[1] = 1)の右辺が0以外の時に条件を満たすようです
そして何故か右辺のオペランドが${'item'.$i}[1]に代入されています
( (${'item'.$i}[1] = "A")なら@heの各要素が("文字列","A",数字)になります)
どうしたらいいでしょうか?
0792nobodyさん
2010/12/02(木) 14:15:19ID:???0793nobodyさん
2010/12/02(木) 15:20:54ID:???0794nobodyさん
2010/12/02(木) 15:33:12ID:???0795790
2010/12/02(木) 16:56:40ID:???失礼しました
0797nobodyさん
2010/12/02(木) 17:09:49ID:???今は知らん。
0799nobodyさん
2010/12/02(木) 17:44:16ID:???0800nobodyさん
2010/12/03(金) 00:17:39ID:???if $cnt <> 0 then
else
endif
だったような
個人的には 「then」 ってなんか好きw
0801nobodyさん
2010/12/03(金) 01:10:22ID:???IF A <> 0 THEN GOSUB 1000 ELSE GOSUB 2000
とかそんな感じだったような。ENDIFはなかった。
完全にスレ違いだな。すまん。
0802nobodyさん
2010/12/03(金) 07:07:22ID:???endifなんて無かった。
0803nobodyさん
2010/12/03(金) 10:37:46ID:???for文の中で、ループ内容を1項目だけ追加させたい場合はどうしますか?
$start=5;
$end=9;
for ($start..$end) {
##$data[$_]にabcが含まれてたらループを1つ追加
if ($data[$_] =~ /abc/i) {
$end++;
}
##$data[$_]を書き出し
print $data[$_];
}
ってやってもダメでした。
0804nobodyさん
2010/12/03(金) 10:56:43ID:???0805nobodyさん
2010/12/03(金) 11:07:30ID:???0806nobodyさん
2010/12/03(金) 11:33:54ID:???掲示板(CGIのページ)にモバイルアドセンスを表示したいんですけどうまく表示できません・・・
どこをいじったら良いのでしょうか?
下の掲示板を利用してます。PCには表示できますがモバイルにはどうしても
無理です。
http://www.kent-web.com/bbs/epad.html
ptel.plにモバイルアドセンス(CGIコード)を書きましたがエラーになります。
携帯からアクセスしたさい、一番上にアドセンスが表示されてれば
問題ないです。
宜しくお願いします。
0807nobodyさん
2010/12/03(金) 11:50:43ID:???【 スクリプト改造依頼スレ】(丸投げ) part7再々
http://hibari.2ch.net/test/read.cgi/php/1222645553/
★三 【 スクリプト改造工房 PART 9 】 ★三
http://hibari.2ch.net/test/read.cgi/php/1143834740/
0808nobodyさん
2010/12/03(金) 15:45:42ID:???0809gfx
2010/12/03(金) 20:37:49ID:???0810gfx
2010/12/03(金) 20:41:32ID:???http://d.hatena.ne.jp/gfx/
Perl忍者君に誘われて2chデビューしましたw
0811nobodyさん
2010/12/03(金) 21:04:26ID:???本人ならハテダに2chデビューしましたって書いてみてくれよ。
0812nobodyさん
2010/12/03(金) 21:04:42ID:???IRCでキチガイに触れてしまったばかりに…
0813nobodyさん
2010/12/05(日) 00:07:53ID:???0814nobodyさん
2010/12/05(日) 17:11:31ID:???さっさと捨てろ
0815nobodyさん
2010/12/08(水) 17:33:34ID:???use utf8; はしてません。
これ自体はちゃんと表示できてるのですが、ファイルを読み込むときに明示的に utf-8 だと指定した方がいいかな?と思い、
ファイルを読み込むときに <:utf8 とすると、読み込んだデータはちゃんと表示されますが、
スクリプトの中に直接書いて表示してる全角文字がすべて文字化けしてます。
'<:utf8' ではなく '<' で読み込めば、文字化けせずすべてちゃんと表示されます。
use utf8; してみましたが状況が変わりません。
binmode STDOUT, ":utf8"; としても駄目でした。
ファイルを読み込むときに <:utf8 を指定しつつ、スクリプトに書いた全角文字が文字化けしない方法ってどうやるんでしょう?
0816nobodyさん
2010/12/08(水) 17:51:37ID:???一箇所でも <:utf8 とか binmode STDOUT, ":utf8" ってやるとスクリプト全体 (use とか require するもの) に影響する。 って感じかな?
0817nobodyさん
2010/12/08(水) 17:59:53ID:???0818nobodyさん
2010/12/08(水) 20:12:49ID:???一方use utf8;しないで書いてるからスクリプト中のutf8文字コードは生のutf8コードのまま。
その両者を混ぜてしまうから化ける。
ってことじゃないだろうか。
0819nobodyさん
2010/12/08(水) 20:33:41ID:???perlio
> :utf8
> Declares that the stream accepts perl's *internal* encoding of characters.
0820nobodyさん
2010/12/08(水) 20:49:34ID:???生のUTF-8nコードでは 0xe6、0x84、0x9bの3バイトだが、
Perlの内部コードでは0x611b。
前者を split // すると (0xe6, 0x84, 0x9b) ができる。単なる3バイトのデータ列としての扱い。
後者を split // すると (0x611b) ができる。内部コード0x611bの「愛」という(splitできない)1文字としての扱い。
0821nobodyさん
2010/12/08(水) 21:53:27ID:???文字化けする理由が >>820 でなんとなく分かった。
が、フラグを立てる理由というか使い道が分からない。
フラグを立ててれば半角全角関係なく文字数が簡単に分かる (ですよね?) とか、そうゆう利点だけな気がしてならないもんで・・・
■ このスレッドは過去ログ倉庫に格納されています