Perlについての質問箱 30箱目
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2007/03/14(水) 22:54:12"There's more than one way to do it" ということで、Perlの奥深さについて皆で語り合い、追求してまいりましょう。
CGIについての質問は板違いです。WEBプログラミング板でどうぞ。
CGIとPerlの区別がつかない人もWEBプログラミング板に行ってください。
(WEBプログラミング板 http://pc8.2ch.net/php/ )
CGIの質問は答えがPerlと全然関係ない話に帰着する場合が多かったりするのでWEBプログラミング板に行って聞いたほうが得ですよ。
このスレでは(CGI以外の)純粋にPerlのみに関係する質問を取り扱っていこうと思います。
スレ違いの質問にはスルーか、速やかな誘導をお願いします。
http://www.perl.org/get.html
● 2006/12/21現在の最新版: 5.8.8
● 2006/12/21現在の開発版: 5.9.3
前スレ
Perlについての質問箱 29箱目
http://pc11.2ch.net/test/read.cgi/tech/1166708139/
リンク集は>>2-3
過去スレは>>4
0453デフォルトの名無しさん
2007/05/07(月) 00:58:21重箱の隅つつき。
p(451 の行の正規表現。(.+?) ではなく(.*?) でなければ
split を用いた他の例と挙動が違うぞ。
$str = q{/foo/bar/baz/quux} で確かめろ。
0454437
2007/05/07(月) 01:10:11>440
単純な範囲演算子で記述できそうに思った私が考え足らずだったようです。
sub { @_[0 .. $#_ - 1] }->(split /\//, $x) は見た目にわかり易いですね。
いろいろ応用できそうだし。しかし、私は露とも思い至りませんでした。
>441
まぁ、そうなんですよね。
$file = "/usr/local/bin/bar"; # ファイル名が与えられて。。。
$fold = join "/", 〜split /\//, $file を使った記述〜; # フォルダ名を得る。
ここで余分に変数を使わず、可読性も損なわない方法がありそな気がしたもので。
>446
splice の第一引数はARRAYしかダメだと諦めてしまったのです。
リファレンスについて熟知すると、こんなやり方に気付くんですね。
自分の頭の硬さとリファレンスに対する理解の浅さを恥じて
精進したいと思います。
まず、>440 さんと >446 さんの方法、どっちを使うか悩みます。
0455デフォルトの名無しさん
2007/05/07(月) 01:17:53いいからFile::Specを使え。
0456デフォルトの名無しさん
2007/05/07(月) 01:19:48いや、可読性が低下するから、いったん配列に入れてからスライスした方がいいと思うぞ
上のは遊びなんだから
0457デフォルトの名無しさん
2007/05/07(月) 02:28:37Dだと [0 .. $ - 1] でいけるんだが。
0458デフォルトの名無しさん
2007/05/07(月) 05:57:16しかし落ち着いて俯瞰すればこういう雑用の可読性を気にする時点でそのソース全体が残飯ですね。
0459デフォルトの名無しさん
2007/05/07(月) 08:33:53標準のキーボードから入力を受け取ってどうやれば入力を反映させれるかわからないです・・・
#!/usr/local/bin/perl -w
require 'jcode.pl';
print"あなたはどれを使いますか?<br/>\n1:ドラゴン<br/>\n2:ゴーレム<br/>\n3:こねこ<br/>\n";
while(<>){
if($_=m/3/){print"これはこねこ"};
};
↑これでは3を入力するたびに、これはこねこって出てくるんですが、
#!/usr/local/bin/perl -w
require 'jcode.pl';
print"あなたはどれを使いますか?<br/>\n1:ドラゴン<br/>\n2:ゴーレム<br/>\n3:こねこ<br/>\n";
while(<>){
if($_=m/3/){print"これはこねこ";$kyara=3}
elsif($_=m/2/){print"これはゴーレム";$kyara=2};
};
これのelsif文が実行されないぽいんですがなんででふか?
頭硬くてすみません・・・
0460デフォルトの名無しさん
2007/05/07(月) 09:30:09でなにをやっているのか良く考えてみ。
0461デフォルトの名無しさん
2007/05/07(月) 11:52:54$_=m/3/ の部分を$_==3 にすると、うまく行きました!
最初$_==3でエラーが出て、良くわからなくて正規表現にすればうまくいくかなとか思って$_=m/3/に直して、(他の部分も少し直して、)それで3の時うまくいったのでてっきり正解かと思いこんでました。
$_=m/3/を$_==3と同じ意味で使ったつもりだったけど、動作は違うんですね。
もうちょっと調べてきます。
ありがとうございました。
0462デフォルトの名無しさん
2007/05/07(月) 12:40:19正規表現、はじめてで意味もよく知らずに=m/3/とかしてたけど、=~/3/とするのが正しかったんですね(汗
==3にすると数字以外の時の入力で(変数は数字ではありませんみたいな)無駄なエラーが出たけど=~/3/ならそういう変なエラーも出ないみたいなので=~/3/を使うことにしました!
↓
$kyara=4;
while($kyara==4){
$_=<STDIN>;
if($_=~/3/){print"これはこねこ";$kyara=3}
elsif($_=~/2/){print"これはゴーレム";$kyara=2}
elsif($_=~/1/){print"これはドラゴン";$kyara=1};
};
もうちょっとがんばってきます!
0463連カキスマソ
2007/05/07(月) 13:11:33if($_=~/3/){処理1}
elsif($_=~/2/){処理2}
とすると、3でも23でも32でも先に$_=~/3/にマッチしてしまう(32なんかは$_=~/2/にマッチさせたい)ので、ちょっと修正しました。
↓
#!/usr/local/bin/perl -w
require 'jcode.pl';
print"あなたはどれを使いますか?<br/>\n1:ドラゴン<br/>\n2:ゴーレム<br/>\n3:こねこ<br/>\n";
$kyara=4;
while($kyara==4){
$_=<STDIN>;
if($_=~/3$/){print"あなたはお昼ね好きのこねこを選びました☆";$kyara=3}
elsif($_=~/2$/){print"あなたはお人よしのゴーレムを選びました☆";$kyara=2}
elsif($_=~/1$/){print"あなたは気の強いドラゴンを選びました☆";$kyara=1};
};
print "(番号=)$kyara";
↑
これなら33111とかって入力でも3ではなく1のドラゴンとして判断してくれます☆
正規表現って便利ですね☆
>>460さん、アドバイス�dクスでした!
0464デフォルトの名無しさん
2007/05/07(月) 13:18:31そこで更に便利な連想配列をどうぞ
0465デフォルトの名無しさん
2007/05/07(月) 13:19:130466460
2007/05/07(月) 16:10:24なんか前向きなやつだなw
どっかの知恵袋のとは大違いだ。
ちょっと補足しておくと、Perlの場合処理対象の
変数を省略できることが多い。
たとえば $_ =~ /1/ なら /1/とか。
$_ = m/1/ と書いちゃうと、マッチの結果を
$_ に代入と解釈されて前の値を壊しちゃう。
ほかにもいろいろあるが長くなるので書かない。
まあがんばれ。
0467デフォルトの名無しさん
2007/05/07(月) 16:18:010468デフォルトの名無しさん
2007/05/07(月) 17:04:17$inkey = <STDIN>;
これで読み取ったときって改行コード入ってない?
そこらへんも気をつけたほうがいいかな
0469デフォルトの名無しさん
2007/05/07(月) 17:27:02Parse対象のXMLにエラーがあった場合に、ユーザー関数をコールバックさせようと考えています。
デフォルトだと
mismatched tag at line **, column **, byte ***, at
/user/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/XML/Parser.pm
line 187
のように出力されてdieします。
0470デフォルトの名無しさん
2007/05/07(月) 17:27:31をみると、ParserがnewされるところでErrorHandlerに自分で作ったもの(例えばMyErrorHandler等)を指定すればよさそうなのですが、具体的になんという名前の関数を用意し、どのタイミングで呼び出されるかなど、よくわかりませんした。
すみませんが、どなたかお分かりでしたらアドバイスをください。
0471デフォルトの名無しさん
2007/05/07(月) 18:14:52ErrorHandlerに無名サブルーチンを渡しておけばパースに失敗したときにコールバックしてくれるんじゃないの?
0472デフォルトの名無しさん
2007/05/07(月) 18:37:28俺も使ったことないけど、フツーに考えて
$parser->{ErrorHandler}で例外をキャッチできるってことなんじゃなないの?
0473デフォルトの名無しさん
2007/05/07(月) 18:59:18�dクスです!参考にして少し書き換えました!
#!/usr/local/bin/perl -w
require 'jcode.pl';
print"あなたはどれを使いますか?<br/>\n1:ドラゴン<br/>\n2:ゴーレム<br/>\n3:こねこ<br/>\n";
while (<>){
if (/[1-3]$/) {chop;$kyara=chop;last;}
};
if($kyara==1){print"あなたはお昼寝好きのこねこを選びました☆"}
elsif($kyara==2){print"あなたはお人好しのゴーレムを選びました☆"}
elsif($kyara==3){print"あなたは強気なドラゴンを選びました☆"};
while (<>){};
こんな感じに☆
>>464さん>
必要になってからがんがります☆(コラ
0474デフォルトの名無しさん
2007/05/07(月) 19:00:380475デフォルトの名無しさん
2007/05/07(月) 19:10:560476デフォルトの名無しさん
2007/05/07(月) 19:14:490477デフォルトの名無しさん
2007/05/07(月) 19:27:33配列や printf を覚えて欲しくなるけど、楽しみながらコツコツやってそうでいいな。
0478デフォルトの名無しさん
2007/05/07(月) 19:38:06ああ、大きなキメラが入るよ。 今年一番の大幅改良だ。
0479デフォルトの名無しさん
2007/05/07(月) 21:43:44俺は車輪を10も20も発明していたらしい。すばらしい!
0480デフォルトの名無しさん
2007/05/07(月) 23:31:32そいつらと鉢合わせずに済むか、を考えるのが難しいかも。
0481473
2007/05/07(月) 23:32:46print system("cls");
と書くと、PCではちゃんと画面クリアしてくれるんですが、サーバにアップしたら画面クリアしてくれませんでした。
ブラウザの画面をクリアする方法って無いんでしょうか・・?
あと、サーバにアップしたら、
while (<>){
if (/[1-3]$/) {chop;$kyara=chop;last;}
};
という部分も全て無視されました。
たぶん、while(<>)の部分がサーバでは無視されてしまってるんだと思うんですが、
どうすれば良いですか?
HTMLでフォームを表示させてそこから入力させるしか無いのでしょうか?
0482デフォルトの名無しさん
2007/05/08(火) 00:03:55そもそも 「コンソールとブラウザの挙動を勉強してください」 としかいえない
ブラウザに対して print ""; でえぇんとちゃうのんかと
STDIN になんもデータ無いからあたりまえです
0483デフォルトの名無しさん
2007/05/08(火) 01:16:200484デフォルトの名無しさん
2007/05/08(火) 02:59:42荒らし以前に板違い。>>1 嫁
0485デフォルトの名無しさん
2007/05/08(火) 05:32:43CGI以外の純粋なperlのみって書いてありますね。
気をつけます。
>>482
なんとなく理解しました。
clsをclearとしても無理だったので普通にフォームからの入力にします。
ご迷惑かけてすみませんでしたm(__)m
0486デフォルトの名無しさん
2007/05/08(火) 09:09:04「大幅改良っ!!キメラぁぁ!!おにいちゃんかっこいいいいぃぃぃい ぃくううううう!」
0487デフォルトの名無しさん
2007/05/09(水) 14:52:59JavaScript 埋め込んでクリアすれば良いんじゃない?
0488デフォルトの名無しさん
2007/05/10(木) 13:07:53・ローカル変数の一覧を取得する方法
・ハッシュの内容をローカル変数に一括して設定する機能(PHPのextract()関数に相当する機能)
があれば教えてください。
0489デフォルトの名無しさん
2007/05/10(木) 13:32:01use Dumpvalue とか。
hashの展開はこんなんでいけるだろ。
while (($key, $value) = each %hash) {
eval("\$$key = \$value");
}
ただし任意のキーが使われる場合はexploitになるんで別の方法で。
0490デフォルトの名無しさん
2007/05/10(木) 13:56:22いいと思うよ。たぶんろくなことにならない。
0491デフォルトの名無しさん
2007/05/10(木) 14:20:02「Perl "HTML::Entities" インストール」でぐぐってもヒットせず困ってます。
0492デフォルトの名無しさん
2007/05/10(木) 14:58:35OSは?
0493デフォルトの名無しさん
2007/05/10(木) 15:06:48ピンと来ないし何だろう。「レン鯖で使いたい」なのかな。
0494491
2007/05/10(木) 15:50:52Linuxです。Perl5.8。
>>493
その通り、海外のレンタルサーバーです。
ただ今はロ−カルのMacでやってるんで、CPANにトライしてみたんですが、最初にいろいろ英語できいてきて、適当に答えてたら設定がおかしくなったのか、
cpan install HTML::Entities
がfetchできないとかでインストールできませんでした。
CPANむずい・・・
0495デフォルトの名無しさん
2007/05/10(木) 16:01:10要するに、ロ−カルのMacにインストールできずに
> CPANむずい・・・
と言ってるわけだ。
こんなこと言っている人がCPANなしでレンタルサーバにインストール
しようってわけね。考えるだけ時間の無駄というものでしょう。
0496デフォルトの名無しさん
2007/05/10(木) 16:04:37READMEに書いてあるじゃん
0497デフォルトの名無しさん
2007/05/10(木) 16:18:17perl Makefile.PL && make && make install
だけどcpanの英語がわからんとか言ってるレベルじゃもっと無理じゃね?
0498491
2007/05/10(木) 18:34:51HTML::EntitiesはHTML::Parserの一部ということでしょうか。
試しにHTML::Parserをインストールしてみると・・・たしかにHTML::Entitiesも印ストールされました。
貴重なヒントをありがとうございました。
#こんな情報どこにあるんですか。http://www.xav.com/perl/site/lib/HTML/Entities.html とか見ても書いてないし。
ちなみにHTML::ParserはMacPortsをつかって
sudo port install p5-html-parser
でいけました。CPANは難しくて分からなかった人でもMacPortsなら楽勝!MacPorts万歳!
0499デフォルトの名無しさん
2007/05/10(木) 18:37:450500デフォルトの名無しさん
2007/05/10(木) 19:02:37http://search.cpan.org/dist/HTML-Parser/lib/HTML/Entities.pm
0501デフォルトの名無しさん
2007/05/10(木) 19:08:36http://search.cpan.org/ をブックマークしておくといいね。
0502デフォルトの名無しさん
2007/05/10(木) 19:08:43cpanモジュールなんだからcpanで調べろよ。
search.cpan.orgでHTML::Entitiesをサーチすれば一番上に出てくる
ttp://search.cpan.org/~gaas/HTML-Parser-3.56/lib/HTML/Entities.pm
を見れば一発でわかるだろ。
0503デフォルトの名無しさん
2007/05/10(木) 22:17:13大きく二つのフレームから構成しています。
1.左フレーム
2.右フレーム
この二つのフレームにそれぞれScrollbarを設けたいのですが、
Frameウィジェットには何故か-yscrollbarオプション等が無く
Scrollbarウィジェットを動作させることができません。
Scrolledで強引に取り付けると、レイアウトがおかしくなります。
どうおかしくなるかというと、
1.Frame内部のウィジェットの配置が決まらない
(HTMLでいう、alignやvalignが効かない)
2.そもそも、実行時にワーニングのような表示が出る(実行はできる)
1.に関しては、スクロールバーを外せば正常に(期待通りに)配置されます。
Tkを使用される方は、こういうフレーム分けしたレイアウトで、
かつ各フレームにスクロールバーを表示させたい場合、どのような
ウィジェットの使い方をされるのか、教えていただけないでしょうか。
0504デフォルトの名無しさん
2007/05/10(木) 22:51:49Tk::Pane provides a scrollable frame widget.
Once created it can be treated as a frame, except it is scrollable.
自己解決です。
スレ汚し申し訳ありません。
0505デフォルトの名無しさん
2007/05/10(木) 23:08:52それぞれウィジェットを作って、その中で更にスクロールバーを設けるんでないかい
0506デフォルトの名無しさん
2007/05/10(木) 23:09:22リロードしときゃよかった
0507デフォルトの名無しさん
2007/05/11(金) 02:34:36に相当するような配列の表現はありますか?
0508デフォルトの名無しさん
2007/05/11(金) 02:56:54できるならやろうと思ってることも
0509デフォルトの名無しさん
2007/05/11(金) 03:40:44みたいな部分を、
($name, $age, $sex) = @foo;
とかで済ませられないかと
0510デフォルトの名無しさん
2007/05/11(金) 05:02:32my $str = 'name=名前,age=年齢,sex=性別';
my ($name, $age, $sex) = $str =~ /name=(.*),age=(.*),sex=(.*)/;
正規表現がアホなのは見逃して。
0511デフォルトの名無しさん
2007/05/11(金) 08:22:51パターンマッチってリストで評価するとそれが返ってくるんだ
よくできてるなあ
でも、
my ($name, $age, $sex) = $str =~ /name=(.*),age=(.*),sex=(.*)/ || next;
という使い方はさすがに無理だった
0512デフォルトの名無しさん
2007/05/11(金) 09:18:49ヒントは演算子の優先順位
(my ($name, $age, $sex) = $str =~ /name=(.*),age=(.*),sex=(.*)/) || next;
または
my ($name, $age, $sex) = $str =~ /name=(.*),age=(.*),sex=(.*)/ or next;
0513デフォルトの名無しさん
2007/05/11(金) 09:34:40普通にパターンマッチをスカラーで評価した時は、
マッチしたかどうかを返すのに対して、
パターンマッチのリストでの評価の代入の評価は、
リストの要素数だから、動作は同じでも意味は違いますよね
0514デフォルトの名無しさん
2007/05/11(金) 09:47:230515デフォルトの名無しさん
2007/05/11(金) 11:34:000516デフォルトの名無しさん
2007/05/11(金) 11:37:09入会申込書とかの該当欄に「週2回」って書いたたちか?
0517デフォルトの名無しさん
2007/05/11(金) 11:54:300518Aransk
2007/05/11(金) 13:09:15何かこちらが勘違いしていたら、ゴメン。
でも、
my @foo=qw(joe 25 male);
my ($name, $age, $sex) = @foo;
print $name,"\n";
print $age,"\n";
print $sex,"\n";
って普通に出来るけど?
0519デフォルトの名無しさん
2007/05/11(金) 13:12:300520デフォルトの名無しさん
2007/05/11(金) 13:19:370521デフォルトの名無しさん
2007/05/11(金) 17:13:50木の実の問題だが、next / last を絡めると途端に可読性が低くなる
気がする。next を絡める予定なら普通に
next if $str !~ /name=(.*),age=(.*),sex=(.*)/ ;
my ($name, $age, $sex) = ( $1, $2, $3 );
でいいじゃんと遅レス。
0522デフォルトの名無しさん
2007/05/11(金) 17:41:10Webで拾った以下の数値切り上げ関数を使用しています。
----------------------------------------
$one = ceil(19.1); # $one = 20
sub ceil {
my $var = shift;
my $a = 0;
$a = 1 if($var > 0 and $var != int($var));
return int($var + $a);
}
----------------------------------------
しかし、このceil関数に、(4.4 * 6000)という数値(26400)を引数として計算すると、26401が帰ってきます。
perl -e 'print sprintf("%.50f", (4.4 * 6000));';
を実行すると、
26400.00000000000363797880709171295166015625000000000000
という結果が返ってきました。
これを回避して、期待したとおりの切り上げ結果を返すにはどうすればいいでしょうか?
0523デフォルトの名無しさん
2007/05/11(金) 17:54:28そのceil関数は整数じゃなければ1足すってだけだろ
0524デフォルトの名無しさん
2007/05/11(金) 17:56:06丸め誤差でググっとけ。
perl -e 'print sprintf("%.50f", int((4.4 * 6000) * 1e6) / 1e6);'
0525デフォルトの名無しさん
2007/05/11(金) 18:02:20銀行の丸めは1桁が偶数のときに小数点以下があれば繰り上げだったっけ?
詳細忘れた
0526デフォルトの名無しさん
2007/05/11(金) 18:05:36今回は全く関係ない。
0527デフォルトの名無しさん
2007/05/11(金) 18:27:480528デフォルトの名無しさん
2007/05/11(金) 18:34:21> これを回避して、期待したとおりの切り上げ結果を返すにはどうすればいいでしょうか?
そんなどこの馬の骨ともわからないサブルーチンを使わずに、CPANで
Math-RoundとかMath-Round-Varとか拾ってきて見てみる。
実地の科学技術計算で使われている、充分な仕様のものがあるはず。
0529デフォルトの名無しさん
2007/05/11(金) 19:10:59$a = 1 if($var > 0 and $var != int($var));
ここの後半の比較式を
int($var) != int($var+0.9999・・・)
にするとか
0530デフォルトの名無しさん
2007/05/11(金) 20:54:42どこの馬の骨かわからないきがしなくもない
0531デフォルトの名無しさん
2007/05/11(金) 21:10:46有名な馬の骨もいるから気をつけな。
0532デフォルトの名無しさん
2007/05/11(金) 21:20:420533デフォルトの名無しさん
2007/05/11(金) 21:24:12現状はまさにそんな感じなんだけど、
($1, $2, $3) っていちいち書くのがなんか気持ち悪くて
どうせ内部で持ってそうなデータなのに
というのが質問の発端
0534デフォルトの名無しさん
2007/05/11(金) 21:25:39数直線の右に丸めるか左に丸めるかが
言語によって違うよね
0535デフォルトの名無しさん
2007/05/11(金) 21:26:440536デフォルトの名無しさん
2007/05/11(金) 22:07:130537デフォルトの名無しさん
2007/05/11(金) 22:10:48ループで回したら?
0538デフォルトの名無しさん
2007/05/11(金) 22:13:24use File::Slurp;
してread_dir
0539デフォルトの名無しさん
2007/05/11(金) 22:13:51で、処理後は closedir で後始末を。
サブディレクトリも探したいなら再帰でググればヒントは見つかるかと思います
0540デフォルトの名無しさん
2007/05/11(金) 22:16:590541デフォルトの名無しさん
2007/05/11(金) 22:25:070542536
2007/05/11(金) 23:47:01readdirをwhileでぶん回す方法でやってみます
0543デフォルトの名無しさん
2007/05/12(土) 00:51:52Unixのfindを使ったことがあるならfind2perlでPerlのコードを生成できるよ。
File::Find
http://search.cpan.org/~nwclark/perl-5.8.8/lib/File/Find.pm
0544デフォルトの名無しさん
2007/05/12(土) 02:54:05よい方法ご存知の方いませんか
@a = ([1,2,3], [4,5,6], [[7,8],[9,0]]);
@b = flatten(@a); # 1,2,3,4,5,6,7,8,9,0
0545デフォルトの名無しさん
2007/05/12(土) 02:58:460546デフォルトの名無しさん
2007/05/12(土) 03:16:52sub flatten(@) { map { ref $_ eq "ARRAY" ? flatten(@$_) : $_ } @_ }
こんなんどうよ。
0547デフォルトの名無しさん
2007/05/12(土) 03:25:10うごかなくて悩んでた。
eqじゃなくて==を使っていたぜorz
0548544
2007/05/12(土) 03:50:18おお、ありがとうございます。
再帰を使うと意外とすっきり書けるもんですね。
頭が硬直化して思いつきませんでした。
ありがたく使わせていただきます。
0549デフォルトの名無しさん
2007/05/12(土) 04:16:20パスのダメ文字が不完全だから、想定外の動作をする。
0550デフォルトの名無しさん
2007/05/12(土) 04:17:18○パスのダメ文字への対応が不完全だから
0551デフォルトの名無しさん
2007/05/13(日) 02:20:04それをperldocで調べようとすると、どういう風にコマンド叩けばいい?
そういう調べものにはperldocは向かない?
0552デフォルトの名無しさん
2007/05/13(日) 03:04:18■ このスレッドは過去ログ倉庫に格納されています