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

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

レス数が1000を超えています。これ以上書き込みはできません。
0001nobodyさん2007/05/30(水) 11:34:01ID:???
Perlのコーディングで困ってる人のスレです。

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

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

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

お勧めサイトは >>2-10

前スレ http://pc11.2ch.net/test/read.cgi/php/1171102883/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
09399322007/09/12(水) 19:18:07ID:w11eoBjq
>>938
具体的なコードを教えてもらってもいいでしょうか?
僕もmapあたりでかっこよくいけると思ったのですが、なかなかそうもいかないというか、
思いつかないんです。


sub sum{
my $a;
foreach(@_){ $a += $_ }
return $a;
}
で、こんなの書いてみました。
いちいち変数を使うあたりがいやです。変数を使わなければmapでも出来るのか?
とか思いますが。
0940nobodyさん2007/09/12(水) 19:45:29ID:???
List::Util
0941nobodyさん2007/09/13(木) 02:52:57ID:???
↑こういうpassは簡単には教えないよーん、みたいなカキコむかつく
0942nobodyさん2007/09/13(木) 04:53:33ID:???
perldoc List::Util
0943nobodyさん2007/09/13(木) 05:20:26ID:???
::
って外部モジュール使うって
意味だったんだね。
0944nobodyさん2007/09/13(木) 08:08:01ID:???
>>939
「変数使わない」って結構大変だし、それで上等だと思うけど?
print eval join '+' , @arr ;
>>943
・・・釣り?
0945nobodyさん2007/09/13(木) 20:30:12ID:QEyk4I0D

$form =~ m/([++,,、、。。__\//  ])/)

正規表現で上記のような記号を抽出しようとすると、
どうもうまく抽出されません。

たとえば「?」が半角の。になってしまいます。

文字コードはjcode::sjis2euc(\$form)で事前に
EUCにしておりますが(ソースコードもEUCです)、
何か対策等ございましたらご教示いただきたく思って
おります。

宜しくお願いいたします。
0946nobodyさん2007/09/13(木) 20:53:20ID:???
まずは。。 []内に2バイト以上の漢字コード書いても1バイトごとのぶつ切りで指定してる
ことになる

あと、日本語EUCと言えども文字の並びによっては別の文字と同じ文字コードパターンがきて
文字の境目が部分だけでは判断できにくくなる

対策としては先頭から1文字ごとに分割して判断するのが素直なやり方
0947nobodyさん2007/09/13(木) 21:15:58ID:???
UTF-8 でがんがろう。
0948nobodyさん2007/09/13(木) 21:53:49ID:???
>>946-947
アドバイス感謝です。

できないことがわかりましたので、早速以下に変えてみました。
報告とさせていただきます。
-------------------------------------------------------
my $form_length = length($form);
for (my $i = 0; $i < $form_length; $i++) {# 文字を1文字ずつ処理(日本語対応)
  my $form_substr = substr($form, $i, 1);
  if ($form_substr =~ /[\x80-\xff]/) {
    $form_substr = substr($form, $i++, 2);
  }
  if(($form_substr eq '+') ||
    ($form_substr eq '+') ||
    ($form_substr eq ',') ||
    ($form_substr eq ',') ||
    ($form_substr eq '、') ||
    ($form_substr eq '、') ||
    ($form_substr eq '。') ||
    ($form_substr eq '。') ||
    ($form_substr eq '_') ||
    ($form_substr eq '_') ||
    ($form_substr eq '/') ||
    ($form_substr eq '/') ||
    ($form_substr eq ' ') ||
    ($form_substr eq ' '))
  {
    &error_out();
    last;
  }
}
0949nobodyさん2007/09/13(木) 22:06:55ID:???
なんで素直にuse utf8しないのだろう
ifでくくるにしてもgrepなりfirstなりで検索するとか
ハッシュテーブル使うとかすりゃいいのに・・・

if (grep{ $_ eq $str } @mojilist) {

if ($mojilist{$str}) {

$pat = join '|', mapquotemeta @mojilist
$form =~ m/($pat)/
0950nobodyさん2007/09/13(木) 22:12:41ID:???
書いてる途中で送信してしまった・・・
足りない部分は想像力で補ってくれ

if (grep{ $_ eq $str } @mojilist) {
・・・

%mojilist{$str} = map { ($_=>1) } @mojilist;
if ($mojilist{$str}) {
・・・

# このやり方はすごく効率が悪い
$pat = join '|', map { quotemeta $_ } @mojilist;
$form =~ m/($pat)/;
0951nobodyさん2007/09/14(金) 14:13:47ID:???
初心者なんですが質問させてください。
Perl言語を用い、fpingの出力ファイルから、
ラウンドとリップ時間のみの数値列を出力するプログラムを作成せよ。
という宿題がでました。
何から手をつければいいかわからない状態なので、もしよかったら教えてもらえないでしょうか?
0952nobodyさん2007/09/14(金) 16:04:26ID:???
>>951 >>1
0953nobodyさん2007/09/14(金) 20:30:20ID:???
> 書いてる途中で送信してしまった・・・
> 足りない部分は想像力で補ってくれ

エスパー能力を要求する回答者イラネ
0954nobodyさん2007/09/15(土) 13:34:20ID:???
わざわざ答えてくれてるのに、ブーたれる初心者イラネ
0955nobodyさん2007/09/15(土) 16:49:52ID:iajdiFDw
シミュレーションプログラムを書いてみました。
ループ回数を増やすほど理論値に近似しますのでできるだけ増やしたいですが、
あまり増やして、数十分も処理を続けられると困ります。

ループ1回あたり何秒かかるのか。
もしくは1秒で何回ループさせられるのかを調べるコードを教えてくだしあ。
0956nobodyさん2007/09/15(土) 16:56:47ID:???
>>955
use Benchmark ;
09579552007/09/15(土) 17:03:02ID:iajdiFDw
>>956
早速ありがとうございます。
英語読めないんですがperldocちょっと読んでどうやらtimethisでできそうな気が。

でやりましたら、
error 0.168701171875 at (eval 6) line 40.
なんて表示されました。

どういうエラーでしょうか。

my $code = q{コード};
timethis(1,$code);
って感じでやってみました。

「コード」内で別モジュールを使ったり、コード内にない自作関数を使ったりするのはありですよね?
それともrequirやuseもコード内でやるべきですか?

イマイチうまくいきません。でもあと少しっぽいのでもう少しだけアドバイスお願いしまうs。
09589552007/09/15(土) 17:05:33ID:iajdiFDw
一応コードの40行あたりの
die
をコメントアウトしてやりなおしたら
Illegal division by zero at (eval 6) line 47.
こんなエラーにかわりました。

改善策わかりますでしょうか?
09599552007/09/15(土) 17:06:51ID:iajdiFDw
すいません括ってる範囲を変えたらなんか上手くいったみたいです。
もうちょっと挙動を調べて又きまう。
09609552007/09/15(土) 17:24:13ID:iajdiFDw
特に問題なしでした。
0961nobodyさん2007/09/15(土) 21:08:38ID:???
簡単なエラーすら理解できないなら、大学辞めればいいと思うよ。
0962nobodyさん2007/09/15(土) 22:37:55ID:???
これで大学生だったら噴くぞ。
0963nobodyさん2007/09/15(土) 23:36:16ID:???
webprogから入ったものですが、最近ちょくちょくPerlにやらせることができそうな
事をみつけてはコーディングしてみています。

複雑なループ処理等になってくると全てがきっちり動いてるのか確認大変ですね。
今なにをやっているかという具体的な中身を視覚化してくれるモジュールなどあるのでしょうか?

自分で「よし、まずはこの変数の動きをチェックしてみよう」みたいな事をやっていくのにも限界があるなと思うこのごろです。
0964nobodyさん2007/09/15(土) 23:40:09ID:???
デバッガって知ってるか。
09659632007/09/15(土) 23:47:45ID:???
>>964
確かエラーを見つけるものですよね?
エラー修正はそこまで苦労しないのです。

普通に何行目あたりに構文エラーがあるなどとわかりやすいですし。
問題は動いてるけど、この出てきてる数値が果たして本当に合っている数値なのかってことです。

それのコードの検証作業を補助してくれるものはないのかなと思ったのですが。
以前にフローを視覚化するなんとかがあるとかないとかって聞いたことがあります。
Perlではなかったかもしれませんが。

実際はもっとわかりやすく、実際に動かした時の逐一の動作を見せてくれると楽だな。と。
0966nobodyさん2007/09/15(土) 23:49:53ID:???
違うから調べてこような。
0967nobodyさん2007/09/15(土) 23:59:55ID:???
>>965
つ print
0968nobodyさん2007/09/16(日) 00:05:24ID:???
どんな数値かどうか知りたいならそれこそPerlでできることだろ
追加書き込みでログ保存するサブルーチン書いて

&func("\$val=$val");
って書いていけば簡単にできると思うが
0969nobodyさん2007/09/16(日) 00:18:53ID:???
デバッガってあまり使われてない気がする
まぁ、プログラム作ってる最中っていうより、プログラムできあがったけど
なんか動作があやしいって時に使うもんだけど。
自分がテストやんなくていいなら使わないか。。。
0970nobodyさん2007/09/16(日) 02:17:16ID:???
WindwosのGUIのデバッガは有料が多い気がする。

とりあえず、perlデバッガなら、w 変数名 と c だけ覚えておけば、
変数をヲチできるよ。

大体は、print文や、ログの事後解析で事足りるから、
デバッガは殆ど使わないな。
0971nobodyさん2007/09/16(日) 03:26:56ID:???
あとData::Dumperかな。
よく多重のハッシュを使うから、これがないとね。
0972nobodyさん2007/09/16(日) 07:21:24ID:y2OdqWq5
my @list = qw/3 7 4/;
print (sort{$a<=>$b}@list)[0];

これで上手くいきません。並べ変えた0番目の要素を表示したいのです。
別配列に一旦入れるのは避けたいです。
確かナイスな方法があったような気がするのですが思い出せません。
お願いします。
0973nobodyさん2007/09/16(日) 07:33:41ID:???
print +(sort{$a<=>$b}@list)[0] . qq{\n};
0974nobodyさん2007/09/16(日) 07:43:09ID:y2OdqWq5
>>973
すっげえ男前。
忘れてたのとは違うやり方だけどナイスですね。

しかしどういう理屈でしょうか?
[0..1]とかも使えちゃいましたし。
プラス演算子がおかれると何故配列として認識してもらえるのでしょうか。
0975 ◆TWARamEjuA 2007/09/16(日) 07:47:24ID:????2BP(6825)
print 式
print(式)
0976nobodyさん2007/09/16(日) 07:52:15ID:y2OdqWq5
>>975
回りくどい。
0977nobodyさん2007/09/16(日) 08:32:37ID:???
>>974
scalar() と似たもんだ。
print scalar ( (sort{$a<=>$b}@list)[0] ) ;
print + (sort{$a<=>$b}@list)[0] ;

配列スライス出力時に、+, scalar 共に使うのも良くない。
print + ( sort{$a<=>$b}@list)[0..2] , qq{\n};
print + ( sort{$a<=>$b}@list)[0..2] . qq{\n};
print scalar ( ( sort{$a<=>$b}@list)[0..2] ) , qq{\n};
print scalar ( ( sort{$a<=>$b}@list)[0..2] ) . qq{\n};
きちんと挙動確認して使うならいいかもしらんが後に読みなおした時
(もしくは他の人が読んだとき)に混乱するのは必至。

、、、が深くは突っ込まんでくれ。理解はしている(つもり)だが、
素人の説明を鵜呑みにするのはイクナイ。ここらへんは本とかperldocとか
読んでくれ。


これだとなんなんで。も一つ
printf "%d\n", sort{ $a <=> $b } @list ;
こっちは配列の中身が整数であることを「保証されない」時痛い目に
合うこと受け合いさ。
0978nobodyさん2007/09/16(日) 09:19:49ID:???
演算子の優先順位をきちんと理解すればわかるはず。

しかしいつも思うのだがO(n)で求めることができる最小値をO(n*log(n))はかかるソート使って求めるのは抵抗あるなあ。組み込みだからよっぽど長いのくわせない限り十分速いのはわかるのだが
0979nobodyさん2007/09/16(日) 10:19:55ID:y2OdqWq5
>>977
すいません。ありがとうございます。

print \(sort {$a<=>$b} @array);
こうすると配列のリファレンスができると思ったらできない。
それで思い出したけど、
print [sort {$a<=>$b} @array]->[0];
これが以前よく使っていた方法でした。これなら配列スライスも安全に
print @{[sort {$a<=>$b} @array]}[0..1];
とできますし。

()の中に配列が入ってるのに[0]でインデックス指定できるかできないか。
+をつけるとできる。scalar()の中に書くとできる。
>>978
その優先順位によって何が行われるんですか。
\()で配列リファレンスができなかったのは\の方が優先低いから先に3つのスカラーが出てきちゃった?
+()だと+が優先高い。。。で、+の優先が高いと何故にインデックス指定ができる?
0980nobodyさん2007/09/16(日) 11:12:25ID:???
いいかげん黒魔術みたいな書き方辞めた方が良いと思うよ。
0981nobodyさん2007/09/16(日) 11:47:48ID:???
配列とリストは違うんだぜ
0982nobodyさん2007/09/16(日) 13:00:23ID:???
> \()で配列リファレンスができなかったのは\の方が優先低いから先に3つのスカラーが出てきちゃった?

根本的に間違ってますから
0983nobodyさん2007/09/16(日) 14:12:00ID:???
sub root{
my @get = @_;
sort @get;
return $get[0];
}

print root 1,2,3;

普通は
print &root(1,2,3);
と書くでしょうし、それが一番わかりやすいですが、括弧なしで書いた場合は一体いくつまでをサブルーチンの引数と解釈されるんでしょうか?
0984nobodyさん2007/09/16(日) 14:27:19ID:???
>>983
挙動は変らんよ。与えられたリストを全部もってく。
print root 3,4,5, print q{hoge} ;
なんてマネしたら当然1 が返る(sort の行をきちんと機能させた場合)
がそれは、
print &root( 3,4,5, print q{hoge}) ;
と同じわけで本来の挙動だ。

お前さんが prototype の事を質問しているのだとしたら全く別の話。
0985nobodyさん2007/09/16(日) 14:35:03ID:???
>>972
http://perldoc.jp/docs/perl/5.6.1/perlfunc.pod
> 括弧を使うときには、単純な (しかし、ときには驚く結果となる)
> 規則が適用できます: 関数に見えるならば、それは関数で、
> 優先順位は関係ありません。
0986nobodyさん2007/09/16(日) 14:42:55ID:???
こんにちわ。
コーディングとちょっと違うかもしれませんがお願いします。
test.plを実行すると自分のパソコンのスペックで15分くらいかかります。
ファイル操作とか何もしない、コード内完結型?のコードなので、処理をさせてる間
他の作業をパソコンでしたいのです。

簡単に言うとtest.plの完遂を待ってる時間に2ちゃんねるでもして暇をつぶしたいのです。
なので30分かかってもいいので、test.plのCPUやメモリの最大使用率を通常の1/2にしたいのです。
可能でしょうか?
09879632007/09/16(日) 15:21:39ID:???
>>966-968
う〜ん。なんか伝わってないような。

例えばsort関数が何をしているか視覚化して初心者に説明しなさい。
ってな時にsort関数のコードを渡せば自動で視覚化してくれるモジュールがあればなってことです。
自分でsort関数と同じ関数を作って、そこにごちゃごちゃと視覚化のためのコードを書くのは、
簡単な関数の時にしか「簡単じゃん」とは思えないですよね?

いや、簡単だというならsort関数の視覚化をこの場でやってもらえればいいんですけどね。
my @col = (4,6,2,98,2,1345,22);
この配列をsort関数がどういう手順でどういう事をしてるかを目で見えるようにするコードを「簡単に」どうぞ。
0988nobodyさん2007/09/16(日) 16:00:13ID:???
>>986
コードにメモリ食う個所がどれくらいあるか見ないとニンともカンとも・・
0989nobodyさん2007/09/16(日) 17:10:58ID:???
my @array;
for (1..100){ push @array,$_ }
@array = sort {$a<=>$b} @array;
my $tr = (@array * (1-0.68)/2);
print $tr;
print "\n";
splice @array,0,$tr;
splice @array,-$tr;
print "@array";

このコードですが、$trを表示すると16になります。
しかし$trをintすると15になります。
さらに、spliceに使われてる$trもどうも15として動いてるようです。

15.999999999という状態になっているのか。
こんな事があるなんておもいませんでした。
print すると整数のみなのに、実際は小数付きの数字という事は常に想定しておかないといけないことなのでしょうか?

print "\n\n";
print ($tr != 16);
をすれば1と表示されます。だからそんなに問題はない?
でもなんか混乱しています。何故こんなことになってるのでしょうか?
0990nobodyさん2007/09/16(日) 17:23:41ID:???
>>989
浮動小数点誤差の蓄積?
Math::BigFloat を試すと幸せになるかもしらん。
0991nobodyさん2007/09/16(日) 17:27:58ID:???
>>990
英語の説明しか身吊りません。orz
使い方がわからない。
0992nobodyさん2007/09/16(日) 17:33:39ID:???
>>991
すまんが、
ttp://corn.2ch.net/php/kako/988/988728069.html
の5〜10嫁。
0993nobodyさん2007/09/16(日) 17:51:31ID:rriFOokp
プログラム全体で使用する設定(各種パスやデータベースハンドルなど)を
別ファイルにまとめておきたいのですが、
どのような仕組みにすればいいのでしょうか。
例えばconf.pmに変数として$path=/home/...;
などと書いて、スクリプト本体でrequireしてprint $path;としてもダメですよね・・・
ダメダメな質問ですみませんが、お願いします。
0994nobodyさん2007/09/16(日) 17:53:04ID:???
>>992
すいませんでした。

use Math::BigFloat;
my @array;
for (1..100){ push @array,$_ }
@array = sort {$a<=>$b} @array;
my $tr = Math::BigFloat->new((@array * (1-0.68)/2));
print $tr;
print "\n";
splice @array,0,$tr;
splice @array,-$tr;
print "@array";

としましたら表示が16で、動作も16になってくれました。
これって結構重要なことですよね。
乱数とかを扱う場合特にちょっとした誤差でとんでもない違いが生まれてしまいますし。

で、一体なんなんです?
15.99999999になってるのは別にいいんです。比較でもちゃんと!=16で真出しますし。
なんでprintでは勝手に四捨五入されてしまう?のでしょうか。

誤差が気になるよりもprintでの表示が違う事の方が気になります。
0995nobodyさん2007/09/16(日) 17:58:04ID:???
とりあえず大きい小数点がいつ生まれるかわからないから、
誤差が怖い時は常にbigfloatに入れて使っておけばいいんですかね。
0996nobodyさん2007/09/16(日) 19:33:23ID:???
次スレはないんでしょうか?
ここで質問しても流されそうですが・・・

一応してみます。回答お願いしますm(__)m

@test[-10]の本来のインデックス番号?って簡単にわかりますか?
spliceしないで、頭10番目から末尾10番目を得たいんです。
ごちゃごちゃしないと無理ならspliceでもいいんですけれど。
0997nobodyさん2007/09/16(日) 19:52:40ID:???
Perlコーディング初心者質問スレ Part 56
ttp://pc11.2ch.net/test/read.cgi/php/1189939783/
0998nobodyさん2007/09/16(日) 19:57:31ID:???
>>996
初心者にもほどがあるってレベルなんだけど、釣りなのか?
本気なら、もう少し本なり入門サイトなり見てから質問してくれよ
0999nobodyさん2007/09/16(日) 20:01:49ID:???
use Math::BigFloat;
my $tr = Math::BigFloat->new((@array * (1-0.68)/2));

と書くの大変なので

my $a = use Math::BigFloat;
my $tr = $a->new((@array * (1-0.68)/2));

と書いてみましたがエラーでした。
こういう意図を実現するのは無理ですか?
小数の計算をさせた上で配列のインデックスにする場合はBigfloatしておかないと危ないです。
やってない$trに
$array[-($tr +1)];
とすると実質インデックスが2個変わってしまいます。
15.999だったのが、+で16になり、さらに1が足されて17になる。
そんな現象を確認しました。

簡単な記述方法はないでしょうか。
1000nobodyさん2007/09/16(日) 20:07:07ID:???
新しいスレに再投稿させていただきました。
10011001Over 1000Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。