Perlについての質問箱 20箱目
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2005/11/06(日) 23:13:31"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
● 2005/03/17現在の最新版: 5.8.7
● 2005/03/17現在の開発版: 5.9.2
リンク集は>>2-3
過去スレは>>4-5
0153デフォルトの名無しさん
2005/11/15(火) 02:15:58ページ番号が0のとき、 1〜10までを表示
ページ番号が1のとき、11〜20までを表示
・・・
ページ番号が$nのとき、($n*10+1)〜(($n+1)*10)までを表示
って作ればいい。
0154デフォルトの名無しさん
2005/11/15(火) 02:59:430155デフォルトの名無しさん
2005/11/15(火) 06:05:47CGIと一言も言ってないけどCGIでしょ?
続けるならWebProg行きなよ
0158デフォルトの名無しさん
2005/11/15(火) 09:53:43おまい、いろいろ不自由なんだな・・・
ガンガレ
0159デフォルトの名無しさん
2005/11/15(火) 14:15:26レスありがとうございます。Sendmailの本は持っているのですが、よく分かりませんでした。
適切なスレを探しているのですが、よく分かりません。もしよければ、質問できそうなスレを教えて貰えませんか?
0160デフォルトの名無しさん
2005/11/15(火) 15:07:14くだらねえ質問はここに書き込め! Part 115
http://pc8.2ch.net/test/read.cgi/linux/1131686280/
くだらない質問はここに書き込め!44
http://pc8.2ch.net/test/read.cgi/unix/1128698100/
0161デフォルトの名無しさん
2005/11/15(火) 16:15:01いや、sendmail本はともかく RFCの確認含めて、基礎的な部分を自分で
調べられない程力不足であれば、人に聞くだけでは怪しいままなので
そういう他のサイトに被害が及びそうなことはやめてくれよ。
0162デフォルトの名無しさん
2005/11/15(火) 16:24:56まじめにじっくり勉強しろという方が親切だろうな...
0163デフォルトの名無しさん
2005/11/15(火) 17:14:59AN HTTPDで鯖を立て、そこにプログラムを置いて実行するようにしたのですが、動きません。
一瞬読みに行ったような動作はするのですがすぐに終わり、何も変化しません。
詳しい先輩に聞いたら「perlがぶっこわれてんじゃね」といわれたため、入れなおしてみたりいろいろしてみましたが変化ありません。
なぜでしょうか?非常に困っているために解決方法を教えていただきたいのですが・・・
AN HTTPDのver 1.42n
Active Perlのver v5.8.7 built
AN HTTPDの設定 拡張子.pl,.cgi 実行プログラムC:\Perl\bin\perl.exe
よろしくお願いします。
0164デフォルトの名無しさん
2005/11/15(火) 17:16:40それ、Perl の質問じゃないんじゃないの?
0165デフォルトの名無しさん
2005/11/15(火) 17:25:34ここで検索しな。
http://find.2ch.net/
sendmail スレもいくつかある。
0166デフォルトの名無しさん
2005/11/15(火) 17:35:23すみませんでした。別のところいってきまつ
0167デフォルトの名無しさん
2005/11/15(火) 19:57:070168デフォルトの名無しさん
2005/11/15(火) 20:10:17> myで宣言した変数って、いらなくなったらundefしたほうがいいの?
時と場合による。
0169デフォルトの名無しさん
2005/11/15(火) 20:17:29smbclientが実行される度にコンソールに標準出力が出るのですが、これを表示しないようにすることは可能ですか?
0170デフォルトの名無しさん
2005/11/15(火) 20:21:04http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq8.html#How_can_I_capture_STDERR_from_an
0171デフォルトの名無しさん
2005/11/15(火) 21:44:12これを指定すると、変数はすべて宣言しなければならないと
いう規制がつきますよね?
宣言とはmyを付けることなのでしょうか?
それにしては、いきなり
$a = "aaa";
とか書いても怒られないんですよね。
どういう解釈をすればいいのでしょうか?
0172デフォルトの名無しさん
2005/11/15(火) 21:48:08$a と $b だけは特別。 perldoc perlvar 参照。
0173デフォルトの名無しさん
2005/11/15(火) 22:00:32それもそうだね。ありがとう。
0174デフォルトの名無しさん
2005/11/15(火) 22:14:23my な変数はできるだけ内側のスコープで宣言しておいて、「要らなくなった時には見えなくなっている」というのがひとつの理想かと思う。
そういう話でなかったらごめん。
0175デフォルトの名無しさん
2005/11/15(火) 22:33:56> > myで宣言した変数って、いらなくなったらundefしたほうがいいの?
> 時と場合による。
っていうか、そういうことをするのは相当特殊な場合でしょう。
0176デフォルトの名無しさん
2005/11/15(火) 22:35:21もうPerl忘れたぞ。。
スコープを抜けた時にリファレンスカウンタ調べて解放して行くと記憶してるけど
0177名無しさん
2005/11/15(火) 22:43:31決して解放されないって考えた方がよいの?
0178デフォルトの名無しさん
2005/11/15(火) 22:47:15シンボルテーブルにエントリは残るけど
アロケートしたメモリはundefすれば解放されるんじゃねーの
0179デフォルトの名無しさん
2005/11/15(火) 22:48:55いや、それもスコープ抜けたときだったと思う。
ちょっと見てみたけど手元の黒豹本では、
リファレウンスカウントがデクリメントされるのは、
When variables (named values) go out of scope,
とある。
この黒豹本、初版で古いけど、今は違うなんて事はないよね。
0180デフォルトの名無しさん
2005/11/15(火) 22:49:010181デフォルトの名無しさん
2005/11/15(火) 23:00:28my $hoge = 'This is hoge.';
…
}
# 今や$hogeは解放された。×
# 今や$hogeは消滅した。 ×
# 今や$hogeは逝ってしまった。 ○
0183デフォルトの名無しさん
2005/11/15(火) 23:07:30それはプールに戻ったという意味だよね。
その昔、Cで拡張ラリブラリ書いた時に
DESTROYで強制的にメモリ解放させるのは書いた事があるが。
そうじゃなきゃプールに戻るんだったような。
0184銀色
2005/11/15(火) 23:09:28テキストファイルの処理をしているのですが、
多少の加工をした後に重複した行を削除したいのです。
何かいい方法ありませんでしょうか?
0185デフォルトの名無しさん
2005/11/15(火) 23:10:510186銀色
2005/11/15(火) 23:17:44ただ単に重複した行を削除したいと言うことです。
$txt の中に \n で改行されています。
うん。相変わらず説明が下手です。ごめんなさい。
0187デフォルトの名無しさん
2005/11/15(火) 23:23:180188デフォルトの名無しさん
2005/11/15(火) 23:35:38OSに返却されないまでも
Perlのプロセス内では再利用されているって
信じちゃっていいんでしょ?! 信じちゃうから。
0189デフォルトの名無しさん
2005/11/15(火) 23:45:13そういうこと言ってると「malloc() & free()」っていうタイトルで長大なスレッドが・・・
0190デフォルトの名無しさん
2005/11/15(火) 23:50:51調べる力も身に付けようね。
my %got;
foreach (split /^/, $txt) {
print unless $got{$_}++;
}
0191134
2005/11/16(水) 00:55:24僕と>>184さんのどちらの方が意味不明ですか?
と、競ってみたりします。
ところで、みなさんはperlとcのどちらが使い勝手が良いと考えていますか?
0192デフォルトの名無しさん
2005/11/16(水) 00:59:20それがスクリプトクォリティだろ。
0193デフォルトの名無しさん
2005/11/16(水) 01:51:240194デフォルトの名無しさん
2005/11/16(水) 07:42:15ちょうどPerlとCしか使わない(使えない)人間なんだけど
使い勝手って言ったらそりゃPerlでしょ。用途がぜんぜん違うから
比べるのは間違ってるけどね。
0195デフォルトの名無しさん
2005/11/16(水) 08:52:52ほー 興味深いなぁ。 今まで my と local 適当に使ってた(´・ェ・`)
この説明は、要はこういうことなのかな。
■local は、グローバルの同名(?)変数の内容を待避させ(スタック?)、再利用する。
スコープから外れると、使用していたのを破棄して、待避内容を復帰させる。
■my は、スコープ内で呼ばれると用意されるメモリ空間?
コンパイル時とは言っても、cのstaticとは違うんですよね? package内グローバルだと
staticっぽいですね。
ちょっとちがうかなぁ。
まとめると、大きい変数使ったりスピード求めるには、 my の方がいいのかな?
0196デフォルトの名無しさん
2005/11/16(水) 09:08:260197デフォルトの名無しさん
2005/11/16(水) 09:26:00> 大きい変数使ったりスピード求めるには、 my の方がいいのかな?
つか、そもそも用途が全然違うだろ。馬鹿か?
0198デフォルトの名無しさん
2005/11/16(水) 09:47:320201デフォルトの名無しさん
2005/11/16(水) 10:24:57全然当てはまんない。だから、そもそも用途が違うって。入門書読め。
0203デフォルトの名無しさん
2005/11/16(水) 15:06:02そりゃ、スコープを抜ければ待避させたデータの再利用が可能だし、
入門書では他のサブルーチンからでも参照できるとか書いてるけど
意図的にそういうスクリプト書く奴の気が知れない。
基本はTMTOWTDIだが、一応正しい使い方はlocalでできてmyでできない宣言。
→型グロブやファイルハンドルの宣言、特殊変数の一時書き換えなど。
myはレキシカル変数の宣言。
スコープの外からリファレンスを使って参照することができるが、基本的にはスコープを抜けると消える。
外から参照されている場合もリファレンス自体が消えた時点で消える。
スコープの外に同名の変数が無く、リファレンス等も用いていないなら挙動は同じといって良い。
きっちり書いてるならundefする必要はないと思われ。
undefされた変数をそれ以降に利用する場合とかはその例外。
これでどう?
0204デフォルトの名無しさん
2005/11/16(水) 15:10:090205デフォルトの名無しさん
2005/11/16(水) 16:44:44script.pl inputfile
script.pl < inputfile
# script
if ( $ARGV[0] eq "" ) {
$fh = *STDIN;
$f_flag = 0;
} else {
open IN, $IN;
$fh = *IN;
$f_flag = 1;
}
while(<$fh>){
処理
}
$f_flag = 1 なら閉じる
としているのですが
どちらもやりわすれたときの良い対処方法が見つかりません。
どのようにしたらいいでしょうか?
0206デフォルトの名無しさん
2005/11/16(水) 17:17:37これが意味不明なのでなんとも回答のしようがないな。
「どちらもやりわすれた」って何?
それ以前の一般的な話として、
openはよく失敗するので戻り値見るべき
単に標準入力か引数のファイルを読みたいだけなら<>でもいいんじゃねーの?
0207デフォルトの名無しさん
2005/11/16(水) 17:20:53@ARGV == 0の方がいいと思う。
0208デフォルトの名無しさん
2005/11/16(水) 17:31:22今、入力ファイルが引数またはSTDINで処理しようとしています。
使用法A:script.pl inputfile
使用法B:script.pl < inputfile
# script
if ( @ARGV[0] eq 0 ) {
$fh = *STDIN;
$f_flag = 0;
} else {
open IN, $ARGV[0] || die "I can't open";
$fh = *IN;
$f_flag = 1;
}
while(<$fh>){
処理
}
$f_flag = 1 なら閉じる
としているのですが
使用法Aも使わず使用法Bも使わなかった時の良い対処方法が見つかりません。
どのようにしたらいいでしょうか?
>単に標準入力か引数のファイルを読みたいだけなら<>でもいいんじゃねーの?
これは知りませんでした。
今、試しましたがやっぱり使用法AもBもしなかったときは
自動的にスクリプトが終了しないですよね?
どうしたらよいのでしょうか?
0209デフォルトの名無しさん
2005/11/16(水) 17:49:55使用法B:script.pl < inputfile
これって、inputfileがなければ入力待ちになるからなぁ。
どうしてもって言うなら、
一定時間入力が来なかった場合、timeoutさせるようにする。
0210デフォルトの名無しさん
2005/11/16(水) 17:55:37標準入力をredirectしてなければ端末がつながってるので
そういうものだな。それがredirectの結果つながったものか
どうかは起動されたプログラム側からはわからないので、
ある程度誤判定をするのを覚悟してファイルの種類で
区別するしかないんじゃないだろうか。-f STDINや
-c STDINあたり。
0211デフォルトの名無しさん
2005/11/16(水) 18:00:14入力を大文字化して表示するスクリプトの例。
#!/usr/local/bin/perl -w
my $input = shift @ARGV or die "Not enough arg.\n";
open IN, '<' . $input or die $!;
print uc while <IN>;
__END__
標準入力を使いたい場合は
script.pl -
のように - を指定。
0212デフォルトの名無しさん
2005/11/16(水) 18:01:45入力が端末かどうかテストすればええのでは? -t fileno(STDIN) あたり。
0213デフォルトの名無しさん
2005/11/16(水) 18:06:470214デフォルトの名無しさん
2005/11/16(水) 18:15:59$hoge[1]=('i'=>6,'c'=>2,'g'=>7);
$hoge[2]=('e'=>4,'l'=>3,'b'=>10,'h'=>11,'j'=>13);
上記のような配列@hoge(要素数100以上)があったとして
$hoge[20]〜$hoge[30]までを切り取って上位に詰める(unshift?)
する場合は、どうしたら良いのでしょうか?
現在は、下記のようにしていますが、もっとスマートな方法は
ありますか?
for($i=0,$j=0;$i<@hoge;$i++) {
if($i>=20&&$i<=30) {
foreach $key (keys %{$hoge[$i]}) {
$tmp[$j]{$key} = $hoge[$i]{$key};
}
$j++;
}
}
for($i=0;$i<@hoge;$i++,$j++) {
if($i<20&&$i>30) {
foreach $key (keys %{$hoge[$i]}) {
$tmp[$j]{$key} = $hoge[$i]{$key};
}
$j++;
}
}
0215デフォルトの名無しさん
2005/11/16(水) 18:18:52ちゃんと読んでないけど
splice()
0216デフォルトの名無しさん
2005/11/16(水) 18:29:00splice(@hoge, 20, 10);
じゃなかったかな。間違ってたらすまん。
0217214
2005/11/16(水) 18:44:45spliceは、配列に場所を指定して配列を追加したりする時に
使いますよね?でも、この場合は、$hoge[20]〜$hoge[30]まで
を上位に"Copy"では無く"Move"させたいのです。
その場合に元の位置にあったデータは消したいのですが…。
どうすれば良いのでしょうか?
0218デフォルトの名無しさん
2005/11/16(水) 18:50:54「上位」って何?
俺用語を使わないで、正しい言葉と、分かりやすいサンプルを。
0219デフォルトの名無しさん
2005/11/16(水) 18:52:35とりあえずマニュアル読もうや。
http://perldoc.jp/docs/perl/5.6.1/perlfunc.pod#item_splice_ARRAY_OFFSET_LENGTH_LIST
my @array = (0..40);
unshift @array, splice @array, 20, 10;
print join ',', @array;
0220212
2005/11/16(水) 18:57:48# script
use FileHandle;
{
my $fh = (@ARGV == 0) ? *STDIN : new FileHandle $ARGV[0];
die "Can't open" unless defined($fh);
die "Can't input from terminal" if -t fileno $fh;
while(<$fh>){
printf ">>> %s", $_;
}
undef $fh;
};
0221デフォルトの名無しさん
2005/11/16(水) 19:05:36ひょっとしてこういう事か?
$hoge[$from] から $hoge[$to] として、
@hoge = (0 .. 40);
$d = $to - $from; # 30 - 20
splice(@hoge, $d, $d); # splice(@hoge, 30 - 20, 10);
0222221
2005/11/16(水) 19:14:49@hoge = (0 .. 40);
$d = $to - $from; # 30 - 20
splice(@hoge, $from - $d, $d); # splice(@hoge, 20 - (30 - 20), 10);
0223デフォルトの名無しさん
2005/11/16(水) 19:16:44もちつけ、splice(@hoge, $from, $d); # splice(@hoge, 20, 30 - 20); じゃないか?
# これじゃ削除だけだけど
>>214
質問の件はspliceで出来るだろうからちょっとツッコミを。
Perlでの擬似多次元配列は無名配列/無名ハッシュを用いて実現されている。
http://www.kt.rim.or.jp/~kbk/perl5.005/perlref.html
> $hoge[0]=('a'=>5,'f'=>9,'k'=>8,'d'=>12);
これは正しくはこう書く
$hoge[0]={'a'=>5,'f'=>9,'k'=>8,'d'=>12};
で、これを読めば分かるように$hoge[$i]の中身はリファレンスなので、
foreach $key (keys %{$hoge[$i]}) {
$tmp[$j]{$key} = $hoge[$i]{$key};
}
ここは、この場合必要としてるのは浅いコピーだから、
$tmp[$j]=$hoge[$i]とリファレンスをコピーしてやれば十分
0224デフォルトの名無しさん
2005/11/16(水) 19:38:550225デフォルトの名無しさん
2005/11/16(水) 19:41:24ごめんなさいspliceの機能を勘違いしてました。
>>221-222
解答ありがとうございました。
unshift @array, splice @array, 20, 10;
で解決しました。
>>223
色々と為になるご掲示ありがとうございます。
勉強になります。浅いコピーは一発で代入できるんですね。
という事は深いコピー…例えば、#hoge[100][100]{$key}のような
構造の配列では$tmp[$j]=$hoge[$i]とできないという事ですか?
0226デフォルトの名無しさん
2005/11/16(水) 19:48:13> という事は深いコピー…例えば、#hoge[100][100]{$key}のような
> 構造の配列では$tmp[$j]=$hoge[$i]とできないという事ですか?
っていうか、それだと浅いコピーです。
0227デフォルトの名無しさん
2005/11/16(水) 19:51:06深いコピーというのは同じものを参照するのではなく、別の写像を作ることを言う。
今回のようにした場合、
$hoge = {'a' => 1};
$fuga = $hoge;
$fuga->{a}='2';
とコピーした先を書き換えると、$hoge->{a}も書き換わってしまう。
$hoge = {'a' => 1};
$fuga = {};
%$fuga = %$hoge;
$fuga->{a}='2';
という風に深いコピーをしてやれば、$hoge->{a}は変わらない。
が、別の領域を用意するということはメモリを余分に使うということであり
必要が無いならやるべきではないな。
0228デフォルトの名無しさん
2005/11/16(水) 19:56:040229227
2005/11/16(水) 20:02:15ああ、言い忘れたけれど
$hoge = {'a' => [1,2,3]};
みたいになると
%$fuga = %$hoge;
じゃ[1,2,3]の部分までは深いコピーは出来ないな。
そういう場合は>>228の言っているCloneモジュールを使うべきかな
0230デフォルトの名無しさん
2005/11/16(水) 20:10:31> という事は深いコピー…例えば、#hoge[100][100]{$key}のような
> 構造の配列では$tmp[$j]=$hoge[$i]とできないという事ですか?
やりたいことにもよるけど、浅いコピーが出来ないのかと訊かれれば、出来ると答える
0231デフォルトの名無しさん
2005/11/16(水) 20:18:42スプライス?
いつも口に出す時こまる。
0232デフォルトの名無しさん
2005/11/16(水) 20:21:51辞書開いて発音記号見れば分かるんだけどな。
http://dictionary.goo.ne.jp/voice/s/02071393.wav
0234デフォルトの名無しさん
2005/11/16(水) 20:26:430235デフォルトの名無しさん
2005/11/16(水) 20:30:13当たり!
0236デフォルトの名無しさん
2005/11/16(水) 20:57:12for文使うのが普通ですか?
0237デフォルトの名無しさん
2005/11/16(水) 21:10:45演算子のxを使う
@hoge = (0) x 100;
0238デフォルトの名無しさん
2005/11/16(水) 21:16:43できた!(・∀・)
ありが�d
0239デフォルトの名無しさん
2005/11/16(水) 21:52:30for文を使うのが普通でしょうか?
(例)@hoge=(1,1,1,1,1,1)なら真、@huga=(1,0,1,1,1)なら偽
0240デフォルトの名無しさん
2005/11/16(水) 21:57:59return scalar(grep($_ != 1, @_)) == 0 ? 0 : 1;
}
0241デフォルトの名無しさん
2005/11/16(水) 22:02:59sub subete_ichi {
return scalar(grep($_ != 1, @_)) == 0 ? 1 : 0;
}
0242デフォルトの名無しさん
2005/11/16(水) 22:09:16全部調べなくても一つ違えばそこで調べ終わっていい。
sub check { $_ == 1 || return for @_ }
0243242
2005/11/16(水) 22:10:19sub check { $_ == 1 || return for @_; 1 }
0244デフォルトの名無しさん
2005/11/16(水) 22:20:34無理に短い、トリッキーなコードを書こうとしないで
後にメンテする人の事も考えてあげて下さい(><)
0245デフォルトの名無しさん
2005/11/16(水) 22:21:330246デフォルトの名無しさん
2005/11/16(水) 22:26:390247デフォルトの名無しさん
2005/11/16(水) 22:27:200248デフォルトの名無しさん
2005/11/16(水) 22:30:570249銀色
2005/11/16(水) 22:31:04適当なところにそのまんまその4行を追加してみたけどダメでした。
3分考えて
open(FILE, ">$filename") or die;
#print FILE $txt;
my %got;
foreach (split /^/, $txt) {
print FILE unless $got{$_}++;
}
close(FILE);
こうしたらうまくできました。
調べる力の不足もそうですが、それ以前の理解度の不足が…
ちょっとずつ勉強していくのでその時はよろしくです。
0250デフォルトの名無しさん
2005/11/16(水) 22:32:21http://search.cpan.org/dist/Quantum-Superpositions/lib/Quantum/Superpositions.pm
all(1,1,1)
0251デフォルトの名無しさん
2005/11/16(水) 22:36:35お前一回WebProg板行ってみろ
0252デフォルトの名無しさん
2005/11/16(水) 22:41:10イヤだ。勘弁してくれ。
■ このスレッドは過去ログ倉庫に格納されています