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

Perl コーディング初心者質問コーナー Part36

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん04/07/14 13:23ID:???
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
0598nobodyさん04/08/12 16:12ID:???
$all= $dbh->selectall_arrayref(qq|select * from test|);
0599nobodyさん04/08/12 16:26ID:???
>>597
fetchrow_array は、
DBの1レコードを1つの array にして取り出すメソッドで、
array の各要素には1レコード中の各フィールドが入る

全レコードを取り出すときには >>598 のようにやるか
あるいは while で回すか
060059704/08/12 17:02ID:???
>>598
selectall_arrayrefがレコード全部をスカラで返してくるのかな?
でもこれSQL文を引数にしるんだな。なんかprepareしたいけど。
>>599
そういうことね。わかりやすい説明thx

ところでprepareって元々何のためあるの?XSS対策にサニタイジングしてくれるわけではないでしょ?
なんかprepareしておいたほうが安全だよって話をよく聞くんだけど。
0601nobodyさん04/08/12 17:06ID:???
>>600
prepareしたければfetchall_arrayrefってのもあるよ。
060259704/08/12 17:29ID:???
>>601
ありがととりあえず
$a = $sth->fetchall_arrayref;
から試したけど、この子はリファレンスの中にリファレンスでさらにリファレンス(これがfeachrow_arrayかな)が入ってるのね。
MySQLの中身がShift_JISで、perlはeucで出力はShift_JISだからちょっと面倒;

とにかくthx!
0603nobodyさん04/08/12 17:36ID:???
>>602
暇だからコーディングしちゃった^^
for ( $i=0 ; $i<$#{$a} ; $i++ ){
jcode::convert( \$_ , "euc" ) foreach @{$a->[$i]};
}
0604nobodyさん04/08/12 17:39ID:???
$i<=$#{$a}
か
$i<@$a
じゃない?
0605nobodyさん04/08/12 17:40ID:???
おまいらレン鯖にシェルでつないで
shell>perl -e "@array=qw/1 2 3 4 5/;
while(@array){print}"

とかしたことある?
060660304/08/12 17:42ID:???
>>604
フォローサンキュ!
0607nobodyさん04/08/12 17:46ID:???
>>603
この場合インデックスはいらないと思うので、

foreach (@$a) {
foreach (@$_) {
Jcode::convert(\$_, 'euc');
}
}

でいいんでねーの?
060859704/08/12 17:56ID:???
ものすごいことが起きたよ・・・・
せっかくだから遣わしてもらおうと思ったら
for ( $i=0 ; $i<=@{$a} ; $i++ ){
                jcode::convert( \$_ , "euc" ) foreach @{$a->[$i]};
}
多分こう書いた。

ループから抜けられず延々HDDがガリガリ(表現悪いけど、処理してる音);
なんとか再起動できたけど、よくエラーにならなかったなとceleron2.7GHz/xp
のすごさを確認したよw

ていうかなんでループから抜けられなかったんだ?もしかしたら
$i=@{$a}
って書いちゃったのかも;
0609nobodyさん04/08/12 18:02ID:???
>>608
もし本当にそう書いたのなら$iは常に最後の要素の次の添字に
なるから、無限に配列が拡張されていきそうだな....
061059704/08/12 18:04ID:???
>>607
それの方が安全そうwと思って試したけどできんかったよ?
それの後に
print $a;
で何も表示されず(リファレンスが表示されると思ったけど)
print @{$a};
でも何も表示なし・・・(リファレンスの配列が・・・)
print @[$a->[0]};
やっぱりだめで何も表示されず・・・・(実際のレコードの中身が・・・・)

603のやつではちゃんと表示されるけど、デリファレンスの方法が違うん?
061159704/08/12 18:07ID:???
>>609
というか$iの中に要素数が代入され、代入成功時の真を返し続ける・・・・・・・
0612nobodyさん04/08/12 18:15ID:???
>>609
その配列無限拡張って何かに使えないかな。
もちろんブロックの中に
last if @$a == 20;
みたいな制限をつけて。
0613nobodyさん04/08/12 18:32ID:???
そんなもんいっぺんに拡張した方が速いから使えない
0614nobodyさん04/08/12 18:36ID:???
>>613
いくつ拡張するかが未定な時には?
一応最大長は決めるが最小長は決めないみたいな場合なんかにつかえるかなと・・・;
駄目か。ごめんよ。
0615nobodyさん04/08/12 19:45ID:???
>>600-601
確か
selectall_arrayref()
ってちゃんとprepareされてるよ。自分でやるか自動でやるかの違い。
http://ash.jp/db/dbi_dbd.htm

でも配列よりハッシュで取り出したいよね。columns_nameをハッシュのキーにして。
$sth->fetchrow_hashref()
みたいなのがあると便利なんだけどしゃ。
0616nobodyさん04/08/12 19:58ID:???
>>615
http://search.cpan.org/~timb/DBI-1.43/DBI.pm#fetchrow_hashref
0617nobodyさん04/08/12 21:16ID:???
mapを知らなくてキレ、カプセル化が出来ないアフォな香具師が居るスレはここですか?
0618nobodyさん04/08/12 23:02ID:???
>>617
しつこいよ君。ここはそうやって他人を罵倒するスレじゃないんだよ。
0619nobodyさん04/08/12 23:04ID:???
今までずっと気になってたけど、fetchってなんて発音すればいいの?
フェッチ?フィーチ?なんかの略だよね?
0620nobodyさん04/08/12 23:06ID:???
>>619
fetch で辞書に載ってますよ。略語でなく。
たぶんフェッチが一般的だけど、読み方は好みで可。

スレ違っててごめんなさい...orz
0621nobodyさん04/08/12 23:12ID:???
map 知らないとかじゃなくて、ここでの論点は副作用を利用してることの方だろ?
>>566,567だけみるとそういう風に誤解されやすそうだけど。
ちゃんと元の投稿>>545 から関連する部分を読んでみよう。
0622nobodyさん04/08/12 23:25ID:???
@foo = map s/aaa/bbb/, @foo;
0623nobodyさん04/08/12 23:30ID:???
>>621
釣り乙
0624nobodyさん04/08/12 23:35ID:???
>>622
だからそこでmapを使うべきじゃないんだってば。
must notじゃなくてshould notね。
0625nobodyさん04/08/12 23:49ID:???
ちょっと乗り遅れたがPerlで大規模なシステムも使われてる
http://d.hatena.ne.jp/keyword/perl
あとどっかの記事によると国内のBlogレンタルサービスはほとんどスクリプト言語で書かれてるんだそうで
0626nobodyさん04/08/12 23:51ID:???
>>624
べきとかって、StrictHTMLじゃないんだから処理効率を最優先させることを非難してもしょうがないよ。
とりあえずもういいんじゃなかなこの話題は。自分の環境にあわせて好きにしようってことでさ。

一応俺の個人的な意見は、「どっちでもいい」だね。まあforeachの処理速度がmapより遅いからね。おやすみ
0627nobodyさん04/08/13 00:17ID:???
いちいち処理速度とか言っている人って気持ち悪い
個人で遊んでるんだから好きにさせて
0628nobodyさん04/08/13 00:23ID:???
>>626
>処理効率を最優先させることを非難してもしょうがないよ。
Perl使っときながら処理効率?はぁ?
んなこと言ってる奴のコードには必ずと言っていいほど
他に見直すべき部分があるんだよな。

>>622
>@foo = map s/aaa/bbb/, @foo;
mapによって@fooは置換済みなのに何で入れ直すの?
mapの動作理解してるか?
062957004/08/13 00:29ID:???
あの一般的にいってmapのvoid.contextより、forの方が早いんですけど。。。
なんか可読性だけで遅いってことになっているような。

use Benchmark;

timethese(-3,
{
map => sub{
my @list = 1..1000;
map { $_ *= 2 } @list;
},
for => sub{
my @list = 1..1000;
$_ *= 2 for @list;
},
}
);
__END__
Benchmark: running for, map for at least 3 CPU seconds...
for: 4 wallclock secs ( 3.13 usr + 0.01 sys = 3.14 CPU) @ 1504.78/s (n=4725)
map: 3 wallclock secs ( 3.00 usr + 0.01 sys = 3.02 CPU) @ 745.27/s (n=2247)

0630nobodyさん04/08/13 00:35ID:???
>>628
いるんだよな、まともなアルゴリズムも組めないくせに
最適化とか言って部分的な高速化にこだわる奴。
ま、素人相手にムキになりなさんな。
063157004/08/13 00:38ID:???
ちなみにmapをvoid.contextでつかってもlistは作られないようだ。perl 5.8.1から(英語は苦手だが。。。)


What's wrong with using grep in a void context?
The problem is that grep builds a return list, regardless of the
context. This means you're making Perl go to the trouble of building a
list that you then just throw away. If the list is large, you waste both
time and space. If your intent is to iterate over the list, then use a
for loop for this purpose.

In perls older than 5.8.1, map suffers from this problem as well. But
since 5.8.1, this has been fixed, and map is context aware - in void
context, no lists are constructed.
0632nobodyさん04/08/13 00:50ID:???
>>629
同じ事を書こうとして先越されたので、ヴァージョンでの差異も含めて追試。

#--- test.p ---
use Benchmark;
@Str = ((qw(aaa bbb ccc aaabbb cccaaa)) x 100);

timethese(-5, {
  for => sub { my @str = @Str; s/aaa/bbb/ for @str },
  grep => sub { my @str = @Str; grep s/aaa/bbb/, @str },
  map => sub { my @str = @Str; map s/aaa/bbb/, @str },
});
__END__

・ActivePerl 5.8.4 Build 810
for: 6 wallclock secs ( 5.71 usr + 0.00 sys = 5.71 CPU) @ 660.25/s (n=3770)
grep: 6 wallclock secs ( 5.65 usr + 0.00 sys = 5.65 CPU) @ 667.26/s (n=3770)
map: 6 wallclock secs ( 5.49 usr + 0.00 sys = 5.49 CPU) @ 656.83/s (n=3606)

・ActivePerl 5.005_03 Build 522
for: 5 wallclock secs ( 5.06 usr + 0.00 sys = 5.06 CPU) @ 782.81/s (n=3961)
grep: 5 wallclock secs ( 5.00 usr + 0.00 sys = 5.00 CPU) @ 808.60/s (n=4043)
map: 6 wallclock secs ( 5.38 usr + 0.00 sys = 5.38 CPU) @ 440.33/s (n=2369)

わざわざ副作用を使おうとするひねくれた子には grep を勧める。
「grep より map の方が読み易い」というのは当然無しだよ。:p
0633nobodyさん04/08/13 01:06ID:???
>>632
追加ということで。(Vine 3.0)

This is perl, v5.8.2 built for i386-linux-thread-multi
Benchmark: running for, grep, map for at least 5 CPU seconds...
  for: 5 wallclock secs ( 5.28 usr + 0.01 sys = 5.29 CPU) @ 848.77/s (n=4490)
 grep: 5 wallclock secs ( 5.29 usr + 0.00 sys = 5.29 CPU) @ 808.32/s (n=4276)
  map: 21 wallclock secs ( 5.44 usr + 0.02 sys = 5.46 CPU) @ 744.69/s (n=4066)

This is perl, v5.8.5 built for i686-linux
Benchmark: running for, grep, map for at least 5 CPU seconds...
  for: 6 wallclock secs ( 5.36 usr + 0.00 sys = 5.36 CPU) @ 1241.79/s (n=6656)
 grep: 5 wallclock secs ( 5.27 usr + 0.00 sys = 5.27 CPU) @ 1261.10/s (n=6646)
  map: 5 wallclock secs ( 5.35 usr + 0.01 sys = 5.36 CPU) @ 1216.98/s (n=6523)
0634nobodyさん04/08/13 01:10ID:???
速度でごちゃごちゃうるさいな
perl使ってる時点で速度とか捨てろよ
何か反論できなくなるとすぐベンチ厨だもんな
これだからまいるよ
0635nobodyさん04/08/13 01:20ID:???
コーディングセンスけなされて、速度でも負けちゃあ
そらまいるわなw
0636nobodyさん04/08/13 01:27ID:???
>>596
自分でも書いているように、
正確には「印字可能」だからではなく、
単に \W にヒットしないからそのままPなだけ。

逆に、符号化する必要のない - とかまで符号化されちゃうけどね。
判って使う分には\Wで手抜きするのもOKなり。
0637nobodyさん04/08/13 02:22ID:???
まあ俺はどっちでもいいがな
0638nobodyさん04/08/13 03:48ID:???
可読性の話じゃなかったのか。
戻り値やパフォーマンス、効率、map/forに限らず
副作用を期待したコードは出来るだけ避けた方が良いと思うんだけど。

>>628
>>622はmapの副作用の有無に関わらず、
@fooが変更されたと言うのがコードから読みとれる。
そもそも、そう言った用途にmapを使うなって話なら同意だけど、
もしmapを使うとしたら配列が変更されたのを明示するって例だと思う。

perl以外の言語を使っている立場から見ると、
mapが勝手に配列の要素を変更するのが気持ち悪いんじゃないかな?
例えば次のコード例で、barの引数 @data にはどんな値を期待するか。

foo(map s/A/B/, @data);
bar(@data);
0639nobodyさん04/08/13 04:15ID:???
例えが悪かった
map{s/A/B/; $_}@data としないと期待通りにならないね。 >>622
0640nobodyさん04/08/13 04:23ID:???
いちいち処理速度とか言っている人って気持ち悪い
藻前はTemplate::HTMLとか使わないで全部自分でHTML printするのかと。
0641nobodyさん04/08/13 05:03ID:???
>>638
可読性の話だよ。>>555 にあるように Perl コミュニティ的には、
何をしているのか分かり易くする為、副作用のみを利用する
ようなコーディングを奨めていない。

しかし (Perl スクリプトという手段の中で) 速度の為に可読性
を犠牲にしなければならない場面というのは確かにある。でも
そういう時でさえ map でやる意味が無い、という事をベンチ
マークが示している。それを理解できない子が吠えてるだけ。

>>640
HTML::Template の仕様が気持ち悪いから必要充分なものを
再発明、というのはありじゃないかな。
0642nobodyさん04/08/13 05:18ID:???
>>629
1.関数の一番最後の式は戻り値になるのでvoid contextじゃない。
2.mapの方だけブロックにするのは不公平。

use Benchmark;

timethese(-3,
{
map => sub{
my @list = 1..1000;
map $_ *= 2, @list;
1;
},
for => sub{
my @list = 1..1000;
$_ *= 2 for @list;
1;
},
}
);

Benchmark: running for, map for at least 3 CPU seconds...
for: 4 wallclock secs ( 3.23 usr + 0.00 sys = 3.23 CPU) @ 1535.91/s (n=4961)
map: 4 wallclock secs ( 3.24 usr + 0.00 sys = 3.24 CPU) @ 1577.47/s (n=5111)
064357004/08/13 05:33ID:ZD4WTWGN
>>642
確かにね。投稿してからきずいたよ。
ただ、ベンチとったら633と同じような結果だったからどうでもいいと思ったんだ。
その2点に注意して、
Benchmark: running for, map for at least 5 CPU seconds...
for: 6 wallclock secs ( 5.42 usr + 0.00 sys = 5.42 CPU) @ 1520.10/s (n=8242)
map: 5 wallclock secs ( 5.03 usr + 0.00 sys = 5.03 CPU) @ 1534.68/s (n=7721)

C:\home\tenho\lavoratory\form>3.pl
Benchmark: running for, map for at least 5 CPU seconds...
for: 5 wallclock secs ( 5.42 usr + 0.00 sys = 5.42 CPU) @ 1520.10/s (n=8242)
map: 6 wallclock secs ( 5.50 usr + 0.02 sys = 5.52 CPU) @ 1486.58/s (n=8200)

C:\home\tenho\lavoratory\form>3.pl
Benchmark: running for, map for at least 5 CPU seconds...
for: 5 wallclock secs ( 5.23 usr + 0.00 sys = 5.23 CPU) @ 1529.42/s (n=8005)
map: 5 wallclock secs ( 5.48 usr + 0.00 sys = 5.48 CPU) @ 1495.26/s (n=8200)

C:\home\tenho\lavoratory\form>3.pl
Benchmark: running for, map for at least 5 CPU seconds...
for: 6 wallclock secs ( 5.50 usr + 0.00 sys = 5.50 CPU) @ 1502.36/s (n=8263)
map: 6 wallclock secs ( 5.53 usr + 0.00 sys = 5.53 CPU) @ 1482.28/s (n=8200)
0644nobodyさん04/08/13 05:44ID:JjTi/TTm
perlの掲示板スクリプトで、書き込みを終えた後ブラウザの「戻る」でバックした時に「クッキーの有効期限が〜」と出てさらに更新すると二重書き込みになってしまうのですがこれを防ぐ方法を御教授いただけませんでしょうか。
まったくの暗中模索状態なので検索ワードだけでもお教えいただければ幸いです。
よろしくおねがいします。
0645nobodyさん04/08/13 06:03ID:???
>>644
△▲ WebProg 初心者の質問 Part9 ▼▽
http://pc5.2ch.net/test/read.cgi/php/1086715675/
0646nobodyさん04/08/13 06:15ID:JjTi/TTm
>>645
ありがとうございます。
過去ログ読んで、ないようなら移動します
0647nobodyさん04/08/13 07:11ID:???
>>642
関数自体が無効コンテキストで呼ばれるので、
戻り値を気にする必要はないと思うよ。
Benchmark.pm の runloop() 参照。
0648nobodyさん04/08/13 09:10ID:???
暴れすぎだよ
0649nobodyさん04/08/13 11:56ID:???
どっちの意見もうなずけるがどっちもキモいな
0650nobodyさん04/08/13 12:14ID:???
可読性ってのは専門家には必要なんだろうが、個人の趣味でやってんなら無用。
ソース公開するってんなら別だが。
Bench取る癖は悪かないが、mapとfor比べたってしょうがないだろ。
複雑な問題解決のためのアプローチの違いとかでやんなさい。
0651nobodyさん04/08/13 12:35ID:???
euc-jpの全角数字を半角数字に変換するのにカコイイコーディングを募集中。
@math = ("0","1","2","3","4","5","6","7","8","9");
for($i=0;$i<@math;$i++){ $value =~ s/@math[$i]/$i/g }
ダサイ・・・・・・・

for($i=0;$i<10;$++){ $value =~ s/\xa3\xb$i/\x3$i/g }
こんなのがokなら一行ですむのに
0652nobodyさん04/08/13 12:37ID:???
>>650
上の方から気になってたんですが、思い切って質問することにしました。
foreachの速さを調べる時はforでベンチ取るんですか?
0653nobodyさん04/08/13 12:41ID:???
>>651
>>530は見た?
0654nobodyさん04/08/13 12:58ID:???
>>652
Perl では for ループも foreach ループも実体は同じ。

foreach (my $i = 0; $i < 5; $i++) { print $i }
for (5..9) { print }

但し "foreach" 修飾子は存在するが "for" 修飾子は
存在しないので、以下のような事はできない。

print $i for ($i = 0; $i < 5; $i++);

まぁ1つの文に ; が複数出てくる事になるので自明だけど。
0655nobodyさん04/08/13 13:10ID:???
>>653
見てなかったorzでもJcodeをコンパイルしてインスールするのが面倒だからダミダ・・・

065665204/08/13 13:16ID:???
>>654
ありがとうございます。
for(@a){print}
print $_ for @a;
と
foreach(@a){print}
print $_ foreach @a;

両方使えるなんて知りませんでした。なんか今後foreach使わずにforだけでやってしまいそうですが
for(@a){print}ができるならforeachってあまり必要ないと思うんですが、そんなことはありませんか?
0657nobodyさん04/08/13 13:56ID:???
知恵を拝借。
%a=( aa=>1 , a1=>1 , a3=>1 , ax=>1 , a8=>1 , a5=>1 );
このハッシュのキーを正規表現にかけて
/\w\d/
に真がでるキーが3個以上あればそれらに対して
delete $a{hoge};
をしたい。

とりあえずいまのとこ思ってるもの↓
@a = grep/\d\w/,keys %a;
undef $a[0] for 0..1;
delete $a{$_} for @a;

undefに配列スライスが使えないなんて知らなかった;

他にもコーディング案があったらレス下さい。
0658nobodyさん04/08/13 13:58ID:???
undef $a[0] for 0..1;
これは
undef $a[$_] for 0..1;
の間違いでした。
0659nobodyさん04/08/13 14:28ID:???
>>657
delete 対象の優先順位とかは無いの?

if ((my @key = grep /\w\d/, sort keys %a) > 2) {
  delete @a{ @key[2..$#key] };
}
066065704/08/13 14:47ID:???
>>659
優先順位はなし。消えればなんでもいい感じ。

delete @a{ @key[2..$#key] };
これいいね!@aってのがミソなのね。知らなかったよ。

ところで全然関係ないことなんだけど、HTMLタグのサニタイジングってどのタイミングでしてる?
今まで受け取って%formを作る際にしてたんだけど、それじゃちょっとよくないから
ちゃんと出力時||使用時にやろうと思うんだけど例えば
$form{hoge}  まだサニタイジングしてない状態
$form{hoge}  サニタイジング済み
にするべきか
$form{hoge}  まだサニタイジングしてない状態
$hramless{hoge}  サニタイジング済み
にするべきかなんだけど、やっぱり送られてきたデータの初期状態は残して置くべきだから
後者でやるべきだよね?

でもちょっとに大きくなってきたので(プログラムが)、きついんだよね。
0661nobodyさん04/08/13 15:01ID:???
>>660
俺は
read(STDIN.$buffer,$ENV{CONTENT_LENGTH});
foreach(split/&/,$buffer){
my($a,$b)=split/=/;
$b =~ s/%(..)/pack("H",$1)/;
$b =~ s/<>\:\;その他自分のサイトで必要ない記号//g;
$form{$a} =$b;
}

でやってる。いちいちその都度やってるとモジュール化もやりづらい。
0662nobodyさん04/08/13 15:07ID:???
>>661
$aもやらければ意味がない。
0663nobodyさん04/08/13 15:36ID:???
ていうか第1引数を置換処理(種類は第2引数)して、returnしてくるメソッド作ればいいだけだろ。

0664nobodyさん04/08/13 17:32ID:???
第1引数を置換処理するのはサブルーチンだろ。少しはPerl使え。
0665nobodyさん04/08/13 17:43ID:???
>>664
呼び出し側からみたら第1っぽいからいんじゃね?
それよりここにいるやつのどれくらいがオブジェクト指向プログラミングできるのかね?

漏れは通販サイトの注文システムを一個の自作モジュールで、面倒andどのページでも使うような
処理をまとめようと思ったが、挫折したorz
どこまでをmainのオブジェクトにやらせて、どこからをモジュール側のオブジェクトにやらせるかの
境界線に苦悩して、最後は状態と振る舞いの境界(意味不明な言い方でごめん)までわからなくなって
結局ライブラリにして終らせた;

むずいんだよ!
0666nobodyさん04/08/13 17:47ID:???
>>665
お前はまずオブジェクトを何に見立てるかができてないんだろ?
例えばメインパッケージを注文を電話で聞くお姉さん。
モジュールの方を、お姉さんが使うパソコン。
とかな。まあお姉さんが注文が来るたびにパソコンを買う(new)なんてのはおかしな話だがなw
0667nobodyさん04/08/13 18:17ID:???
質問です。
$hoge="hoge=1&data=a-a-a&test=23456";
この$valueの中からdata=a-a-aだけを取り出したいです。
data=a-a-aのある位置は毎回違うのでsubstrではできません。
data=に続く文字列も毎回違います。
splitとforeachを使って%formなどを作るのは禁止で、実現したいです。

$hoge =~ s/(data=.*?)&//;
$value = $1;
で一応data=...の後に&がある時は取り出しに成功できますが、
$hoge="hoge=1&data=a-a-a";
などの場合もあるのです。それと
$hoge="hoge=1&data=a-a-a&test=23456&tete=ussgf";
みたいな場合もあります。

どうにかどんなときでもdata=文字列だけを一発で取り出せないでしょうか?
0668nobodyさん04/08/13 18:20ID:???
>>667
if ($hoge =~ /data=.*&/){
$hoge =~ s/(data=.*?)&//;
$value = $1;
}else{
$hoge =~ s/(data=.*)//;
$value = $1;
}

ちと長いな。
0669nobodyさん04/08/13 18:31ID:???
($value) = $hoge =~ /(data=.*?)&?$/;
0670nobodyさん04/08/13 18:32ID:???
($str) = $hoge =~ m/(data=[^&]*)/;
067166704/08/13 18:42ID:???
>>668-9
ありがとうございます
/(data=.*?)&?$/
これ不思議なコードですね;どうしてこれでうまくいくのかな。
$は&?にかかってるけど、&がないときは(data=.*?)にかかるって言う便利なコードですか?

・・・すごいですね>>669さんは。本当にすごいです。
067266704/08/13 18:44ID:???
>>670
それ私も一度試しましたが、駄目でした。
理由はわかりませんが
print $str;
で何も表示されませんでした。
067366704/08/13 18:48ID:???
>>669
($value) = $hoge =~ s/(data=.*?)&?$//;
としたいんですが、置換にすると置換数?真偽?が帰ってくるので
$hoge =~ s/(data=.*?)&?$//;
$value = $1;
とするしかありませんか?一行でバチッとできるとカッコイイんですが。

ものすごく>>669さんからの返事が楽しみです^^(頼り切ってすみません;)
067466704/08/13 18:51ID:???
>>672の発言は私の勘違いでした。すみませんでした>>670さん。
0675nobodyさん04/08/13 19:02ID:???
>>667
for my $hoge (qw(
  hoge=1&data=a-a-a&test=23456
  hoge=2&data=a-a-a
  data=a-a-a&test=12345
)) {
  my($value) = $hoge =~ /(?:^|&)(data=[^&]*)(?:&|$)/;
  print "$value\n";
}
0676nobodyさん04/08/13 19:03ID:???
>>671
669ではうまくいかんはずだが。
ちゃんと試したのかい?
0677669※04/08/13 19:03ID:???
置換しなければならないのだろうか?
そして、ハシュを拒否する事由は?

my $hoge="hoge=1&data=a-a-a&test=23456&tete=ussgf";
my %hash = map +(split /=/), split /&/, $hoge;
printf qq|%s = %s\n|, $_, $hash{$_} foreach keys %hash;

env.:
$ perl5.8.5 -v

This is perl, v5.8.5 built for i686-linux
0678nobodyさん04/08/13 19:10ID:???
>>675は冗長。
$hoge =~ /\b(data=[^&]*)/
で十分。
067966904/08/13 19:10ID:???
>>676
何でうまくいったのか検証してしまったよ(w
068066704/08/13 19:16ID:???
>>675-6
/(?:^|&)(data=[^&]*)(?:&|$)/;
これは>>669さんのやつの変形ですか?でも>>669さんのコードで試したらちゃんと表示されましたよ?
テストが足りないんですかね?もう一度やってみます。

>>677
フォームで送られてくるデータを一度変数に入れて、その後
dataの部分だけをAルーチンに渡して、
それ以外をBルーチンに渡したかったのです。(ルーチンは外部ファイルに作ってあるます)

今はAルーチンとBルーチンの方で、ハッシュにする流れです。先にこちらでハッシュにしてわたしてもいいのですが、
こういうのもできたらカッコイイなと思って質問いたしました。

0681nobodyさん04/08/13 19:21ID:???
>>673
一行でバチッとw
$str = ($hoge =~ s/\b(data=[^&]*)//, $1);
068266704/08/13 19:23ID:???
for my $hoge (qw(
hoge=1&data=a-a-a&test=23456
hoge=2&data=a-a-a
data=a-a-a&test=12345
)) {
($value) = $hoge =~ /(data=.*?)&?$/;
print "$value<br>";
}
>data=a-a-a&test=23456
>data=a-a-a
>data=a-a-a&test=12345

>>676
さっきはうまくいったと思いましたが、↑のソースでやってみたらうまくいきませんでした;
ちゃんとテストしたつもりが勘違いでした;

>>皆様
もの凄く勉強になりました!本当にありがとうございました!それでは失礼します。
0683nobodyさん04/08/13 19:27ID:???
>>681
それ無理じゃないか?
0684nobodyさん04/08/13 19:37ID:???
>>660-663
オブジェクト指向で書く場合は俺はサニタイジングモードを作ってるよ。
sub new {
my $self = shift;
my $buffer = shift;
my %harmless_mode = (
normal => 1,
html => 0,
sql => 0,
csv => 0,
);
みたいなね。(1=on,0=of)

んで状態移行のメソッドを作っておけば一応問題ないかな。まあ俺は小規模プログラムしかやったことないから
大丈夫なだけかもねw


0685nobodyさん04/08/13 20:13ID:???
>>678
確かに >>667 のは \b で充分だね。分かって言ってるんだろうけど一応。

for my $hoge (
  "hoge=1&data=a-a-a&test=23456",
  "hoge=2&a-data=a-a-a&test=12345",
  "data=a-a-a\n",
) {
  my($value1) = $hoge =~ /\b(data=[^&]*)/;
  my($value2) = $hoge =~ /(?:^|&)(data=[^&]*?)(?:&|$)/;
  print "1[$value1] 2[$value2]\n";
}
0686nobodyさん04/08/13 20:33ID:???
>>683
君の頭ん中のPerlでは動かないようだね。
0687nobodyさん04/08/13 20:37ID:???
>>685
後ろの(?:&|$)も必要なんでつか?
0688nobodyさん04/08/13 20:55ID:???
オブジェクト指向ってよくわかんないんですけど、自分でモジュールを作る時に
sub new{
    my $this = shift;
    my $propety = {
           color => shift,
           weight => shift,
           };
    bless $propety,$this;
}
ていうコンストラクタだったとして、あとから他のメソッドで
sub change{
    my $this = shift;
    $this->{color} = "red";
    $this->{changed} = "1";
}
みたいにコンストラクタではなかったchangedっていうプロパティをいきなり作っちゃっていいんですか?
それとも、コンストラクタを
$propety = {
      color => shift,
      weight => shift,
      changed => 0,
      };
みたいにするべきでしょうか?そうしてしまうと新しいプロパティがほしくなった時に
わざわざコンストラクタをいじらなければいけなくて、不便かなと思うんですが・・・
068968304/08/13 21:00ID:???
>>686
ウソ!?って思って試してみた。

for my $hoge (qw(
hoge=1&data=a-a-a&test=23456
hoge=2&data=a-a-a
data=a-a-a&test=12345
)) {
$str = ($hoge =~ s/\b(data=[^&]*)//, $1);
print "$str\n";
}

PCに入ってるPerlでも動かなかったw
0690nobodyさん04/08/13 21:25ID:???
>>689
そのコードの$hogeはReadOnlyな文字列への別名だから、
置換できるわけなかろう。
$hogeをループ先頭でmy $hoge=$_;とすりゃ動いたぞ。(Perl5.8)
#つか、foreachであるべきところをケチってforにすんな、紛らわしい。

ちなみに>>685の問題も回避したい場合、
置換では>>675でもうまくいかんので、
$str = ($hoge =~ s/(?:^|(?<=&))(data=[^&]*)//, $1);
とするといい。
#後ろの(?:&|$)はいらんべ?
0691nobodyさん04/08/13 21:57ID:???
>>688
作法として行儀がいいかどうかは別として、blessされてる以外は
ただのハッシュだからキーの追加だろうが削除だろうが自由にでき
ます。

use fields使ってりゃ別だけどな〜

069268804/08/13 22:39ID:vpkCloyF
>>691
できるのは知ってるのですが、どうするのが一番「十分に拡張的なプログラム」なのかで悩んでます。
0693nobodyさん04/08/13 23:27ID:???
>>692
一番かどうかはともかく一つのやり方として。
コンストラクタでは何もせず、プロパティは全てアクセサ経由で触り、
初期値はアクセサで設定する。

#--- Foo.pm ---
package Foo;
sub new {
  my $class = shift;
  bless { @_ }, $class;
}
sub color {
  my $self = shift;
  @_ or return $self->{'-color'} ||= 'red';
  $self->{'-color'} = shift;
  $self;
}
1;
#--- script ---
use Foo;
my @obj = (Foo->new, Foo->new(-color => 'green'), Foo->new);
$obj[2]->color('blue');
print $_->color, "\n" for @obj;
0694nobodyさん04/08/13 23:34ID:Dbtrqa9I
http://pc5.2ch.net/test/read.cgi/prog/1092405363/
喧嘩を売っています
0695nobodyさん04/08/14 03:15ID:HZTk9WgD
PerlでXMLファイルのデータを引き出したいのですが、方法がさっぱりなのです。
普通にファイルオープンの open(AAA,"<BBB.txt") のように開いて
データを取得することが出切るのでしょうか?

検索で、解説ページなどを探したのですが良いサイトが見つかりません。
(探し方が悪いだけかもしれませんが・・・・)
どこか良いサイトなどがありましたら、教えてください。
0696nobodyさん04/08/14 03:19ID:???
そのぐらい自分で探せないようならあきらめろ
069768804/08/14 10:22ID:???
>>693
例まで書いていただいてありがとうございます。

買う時には必要でなかったプロパティが、買ってから途中でほしくなった場合のために
プロパティを後から追加できるオブジェクトメソッドを作っておいたらオブジェクト指向の利点がどこかで
失われてしまいますか?

sub additional_propety {
  my $class = shift;
  $class->{shift} = shift;
}

第2、第3引数に新規に追加するプロパティとその値を期待します。
■ このスレッドは過去ログ倉庫に格納されています