Perlコーディング初心者質問スレ Part 60
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2009/09/03(木) 23:51:12ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >2 以降
前スレ http://pc11.2ch.net/test/read.cgi/php/1234752149/
0237nobodyさん
2009/11/09(月) 15:37:29ID:???なら死ね。
ブラウザ側には実行(待機)中であることを示して、STDOUTを開放する。
その際SIDかPIDか何かから一意なIDを作っておく。
外部プログラムはforkかcronでバックグラウンド動作させる。
外部プログラムの実行状態はAjaxでもしくは普通にcgiで得られるようにする。シグナルを送れば何%処理中か返すように外部プログラムを作っておくと吉。
妄想だけど多分こんなもんだろ。
0238nobodyさん
2009/11/10(火) 06:22:57ID:???ジョブキューを使うか、デーモン化した方がいいと思うけどな。
0239nobodyさん
2009/11/12(木) 21:37:51ID:???0240nobodyさん
2009/11/16(月) 11:02:56ID:D4PXiJWR0241nobodyさん
2009/11/16(月) 20:59:19ID:???http://spicky.net/vipper/uploads/spicky/9/5/8/1859_zeL8gI2.png
http://spicky.net/vipper/image/1859/
0242nobodyさん
2009/11/17(火) 15:14:45ID:???をPerlで書きたいのですが、どう記述したらいいものでしょうか?
0243nobodyさん
2009/11/17(火) 16:15:15ID:???だいたいこんな感じかね?
use CGI;
use LWP::Simple;
my $q = CGI->new;
my $url = $q->param('url');
if (defined $url) {
get($url);
}
0244nobodyさん
2009/11/18(水) 00:14:38ID:???0246nobodyさん
2009/11/18(水) 23:48:59ID:???ソケット通信ができません。
同じプログラムでapatheで動かすとソケット通信できます。
tomcatで何か設定が必要なのでしょうか
0247nobodyさん
2009/11/19(木) 05:28:08ID:ZQXO+cvVアクセスできるディレクトリやパーミッションに制約があるのでは?
匿名ソケットを使ってるなら知らんけど。
0248nobodyさん
2009/11/19(木) 05:31:23ID:ZQXO+cvV> earch(%{$chanko})
訂正しときますね。
each %$chanko
0249nobodyさん
2009/11/19(木) 05:52:42ID:ZQXO+cvVどう見たいかによる。
数十分かかってもライブで表示したいなら、サーバ(アパッチー?)のタイムアウト設定を十分長くする。
途中経過も見たいなら、ダブルフォークかなにかでバックグランドへ落としたあと
NPHかリダイレクトを使って、チェックした状態を表示。
ユーザが自由にアクセスできるようにするなら、確認用IDを発行するか、クッキーを食わせとく。
一番簡単な解決は、実行終了後に結果をメールで送りつけること。
もしくは結果表示用スクリプトのアドレスを送る。
0250nobodyさん
2009/11/19(木) 15:05:03ID:pgc2wImKeval "use Hoge::Hoge"; if ($@) { use Hoge::Hoge2; }
ある程度うまくいくのですが、失敗する場合もあり、原因がわからずにいます。
まったく同じ内容でpackage名だけが違うモジュールでテストしてみると・・・
(内容は$nameの定義とエクスポートだけ)
Hoge/Hoge.pm -> package Hoge::Hoge;
Fuga/Hoge.pm -> package Fuga::Hoge;
[1] eval "use Hoge::Hoge"; #=>存在するので読み込まれる
[2] eval "use Fuga::Hoge"; #=>存在するのに$@がセットされる($@は空の様子)
※[1]と[2]は別々にテストしています。
[2]のエラーメッセージは
Global symbol "$name" requires explicit package name at ...
use strictをはずして警告を見てみると、
$nameを参照しようとしたときに次のメッセージが出ます。
Name "main::name" used only once: possible typo at ...
[2]の場合も通常にuseすると問題ありませんし、次も成功します。
BEGIN {
eval { require Fuga::Hoge; Fuga::Hoge->import(); }; if ($@) { (略) }
}
[2]だけ失敗してるいまいち理由がわからないんですが、
どういう状況か見当つきますか?
0251nobodyさん
2009/11/19(木) 15:09:31ID:???何をしてるのかわからん。
0252250
2009/11/19(木) 15:17:07ID:pgc2wImKpackage Fuga::Hoge;
our @EXPORT = qw($name);
use base qw(Exporter);
$name = 'myname';
1;
[1]はpackage名だけが違って、それぞれのパスに配置しています。
package Hoge::Fuga;
[1]は
eval "use Hoge::Fuga";
が評価されて$nameをimportできるのに、[2]だけ>>250の警告が出る状況です。
違いがわからないのと、メッセージの意味がじゅうぶん理解できなくて・・・
0253250
2009/11/19(木) 16:26:33ID:???細かい違いがいろいろあるみたいです。
例えばモジュールでget_nameというサブルーチンをエクスポートしているとき、
通常のuseですと
my $name = get_name;
でOKですが、evalではエラーになったりするみたいです。
my $name = get_name(); #カッコがないとエラー
質問させてもらった件も、今ひとつつかみどころがない感じなので、
当面は安定を確認しているBEGINブロック内に記述する方法をとることにして、
尚、ドキュメントをあたってみたいと思います。
>>251さん、ありがとうございました。
0254nobodyさん
2009/11/19(木) 16:40:34ID:???[1]とか[2]とか言ってる読み込み側のプログラムもきっちり
さらしてもらわないとわからんな。
BEGINブロックをつかわないでuseをeval "use 〜" に置き換えると
読み込まれるにタイミングが変わるのでuse strictのコンパイル時
チェックに間に合わないというのはよくある話なんだが、全く同じで
片方だけおかしいとかいうことはないはずだしなんか違いがあるん
だろう。
0255nobodyさん
2009/11/20(金) 16:12:32ID:???read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/,$buffer);
for $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
Encode::from_to($value, 'utf8', 'utf8');
$in{$name} = $value;
}
のようなありきたりのフォーム取得構文を
enctype="multipart/form-data"
に対応させるために
use CGI;
my $query = CGI->new;
my $user = $query->param('user');
のような構文を使って
$in{'name'}=$value形式で受けとりたいのですが
どのように記述したらよいでしょうか?
0258nobodyさん
2009/11/20(金) 18:50:54ID:???フォーム側で
<input type="file" name="tempfile">としたものを
>>256 の方法で受け取り
open(SAVE,"> up.jpg");
binmode(SAVE);
binmode(STDOUT);
print SAVE $tempfile;
close(SAVE);
で保存すると、up.jpgというファイルの中身に
添付ファイルのバイナリでなく、
アップロードしたファイル名のみがテキストで記述されてました。
この場合は、$in{'tempfile'}の中身にはファイル名しか格納されていないことになります
enctype="multipart/form-data"の場合は別の変数になるのでしょうか?
0259nobodyさん
2009/11/20(金) 19:46:05ID:???こうすると、うまくいきます?
print SAVE $tempfile;
↓ ↓
print SAVE <$tempfile>;
0260nobodyさん
2009/11/20(金) 21:19:20ID:???0262258
2009/11/20(金) 21:51:20ID:???調べてみたら、Varsとparamを両方つかわないといけないっぽいです
use CGI;
#データの取得 $in{'name'}で取得
if ($ENV{'REQUEST_METHOD'} eq "POST") {
my $query = CGI->new;
*in = $query->Vars();
}
#ファイルの取得
my $query = CGI->new;
$upfile= $query->param('tempfile');
#ファイルの書込
open(SAVE,"> up.jpg");
binmode(SAVE);
binmode(STDOUT);
while (read($upfile, $buffer, 1024)) {
print SAVE $buffer;
}
close(SAVE);
0263nobodyさん
2009/11/23(月) 03:37:20ID:???させるとき、ifとelsifで書いていくのはなんか非効率的
のような。なんか方法あるのでしょうか?
0264nobodyさん
2009/11/23(月) 05:58:26ID:???あと、サンプルでも$a,$bは使わぬが吉
0265nobodyさん
2009/11/23(月) 06:40:31ID:???switchが欲しいってことだろ
Perlのバージョンが5.10以上なら
use feature qw/:5.10/;
given($a){
when(x){…}
when(y){…}
…
}
と書ける
0266nobodyさん
2009/11/23(月) 07:58:49ID:???$a =(条件1) ? 'x'
:(条件2) ? 'y'
: 'z'
;
0267nobodyさん
2009/11/23(月) 09:00:29ID:???長い式になると優先順位がわかりづらくて使いづらい。。。
0268nobodyさん
2009/11/23(月) 09:19:12ID:???5.10未満ならSwitchモジュールを
switch文
http://www2u.biglobe.ne.jp/~MAS/perl/waza/switch.html
0269nobodyさん
2009/11/23(月) 09:35:35ID:XYWla5BPただこれをやると関数への引数は連想配列へのリファレンスにならざるを得ないから、あまりやらないけど・・・
0270nobodyさん
2009/11/23(月) 10:26:54ID:???こんな感じ?
my %func = ( foo => \&foo, bar => \&bar );
$func{foo}(1, 2); #=> 1 2 in foo
sub foo {
print "@_ in foo";
}
sub bar {
print "@_ in bar";
}
>関数への引数は連想配列へのリファレンスにならざるを得ない
これはどういう意味ですか?
0271nobodyさん
2009/11/27(金) 23:39:39ID:???http://www.ioi-jp.org/joi/2008/2009-yo-prob_and_sol/2009-yo-t2/review/2009-yo-t2-review.html
の問題なのですが、
open(A,">a.txt");
$a=36;$b=20;$c=38;$d=54;$e=42;$f=25;@a={$a,$b,$c,$d,$e,$f}
foreach(@a)
{$one=0;
$two=0;
$thr=0;
if( $_ >= $one){
$one=@a;
$two=$one;
$thr=$two;
}elsif( $_ >= $two )
{$two=@a;
$thr=$two;
}elsif( $_ >= $thr )
{$thr=@a;}}
$total=$one+$two+$thr;
print A"$total";
何がいけないのでしょうか?
perlを勉強初めて数日の私にもわかるように教えていただけないでしょうか
あと、情報オリンピック予選にperlで出てみたいのですが、入力ファイルのtxtファイルを読み込んで、出力ファイルを作るということですよね?
出力するのは、
open(A,">a.txt");
print A "〜";
みたいなので良いんですよね?どうやったらtxtファイルを読み込めるんですか?たとえばtxtファイルの三行目の数をhと定義したりすることはどうすればいいんですか?
0272nobodyさん
2009/11/28(土) 00:15:26ID:???0273nobodyさん
2009/11/28(土) 00:25:39ID:???=== hoge.pl ===
sub calc { eval join '+', ( sort {$b <=> $a } @_ )[0 .. 2] ; }
my @data = <> ;
printf "%d %d\n", ( calc @data[0..9] ), ( calc @data[10..19] ) ;
======
perl hoge.pl INPUT.txt > OUTPUT.txt
0274nobodyさん
2009/11/28(土) 00:41:49ID:BdimRB/2解説だけでどういう問題化わからん。リンクもないし
0275nobodyさん
2009/11/28(土) 00:46:47ID:???0276nobodyさん
2009/11/28(土) 01:55:55ID:BdimRB/2その問題を解くように変えようとするとなると>>273の言う通り一から書き直した方がいいので、
とりあえずそのプログラムで書きたいと思われることを最大限書き直してみた。
use strict; // 初心者ならなおさらstrictとwarningsは入れた方がいい
use warnings;
my($a, $b, $c, $d, $e, $f)
= (36, 20, 38, 54, 42, 25);
my @data = ($a, $b, $c, $d, $e, $f); // 配列は{}じゃなく()。
my($one, $two, $thr) = (0, 0, 0); // foreachの外で使うならforeachの外で初期化しないと毎回0で上書きされる
foreach my $num (@data) { // わかりやすいように$_じゃなくて名前付けておいた方がいい
// ホントは=ない方が処理少ないので=ない方がいいと思う
if ($num >= $one) {
$two = $one;
$thr = $two;
$one = $num; // 初めに$oneに代入したらその後$twoにも$thrにもコピーされるから最後で。
} elsif ($num >= $two) {
$thr = $two;
$two = $num; // 上と同じ理由
} elsif ($num >= $thr) {
$thr = $num;
}
}
my $total = $one + $two + $thr;
open my $wfh, ">", "a.txt" or die "$!"; // 3引数のopen使った方がいいのと、なるべく開いたらすぐ閉じた方がいいのでまとめるべき。
print $wfh $total;
close $wfh; // open したら closeしないとダメ
こんな感じかな。問題解くならPerlの前にアルゴリズムも勉強しないといけない気がするな
0277nobodyさん
2009/11/28(土) 02:14:34ID:???0278nobodyさん
2009/11/28(土) 04:02:22ID:BdimRB/20279nobodyさん
2009/11/28(土) 13:14:18ID:???文脈から分かるとはいえ、一見だと$thresholdや$throttleかも?と思うだろ。
0280nobodyさん
2009/11/28(土) 14:37:12ID:???>>275さんの問題の通りこのような入力例が与えられて、出力しないといけないのですが、
my($a, $b, $c, $d, $e, $f)
= (36, 20, 38, 54, 42, 25);
のように自分で打たずに、txtファイルから読み込む方法を教えていただけないでしょうか。
0281nobodyさん
2009/11/28(土) 14:41:24ID:???#一行ずつ$numに代入する。
}
こんな感じかな?
0282nobodyさん
2009/11/28(土) 14:55:14ID:???my($one, $two, $thr) = (0, 0, 0);
foreach my $num (b.txt)
{
if( $num >= $one)
{
$two=$one;
$thr=$two;
$one=$num;
}elsif( $num >= $two )
{
$thr=$two;
$two=$num;
}elsif( $num >= $thr )
{
$thr=$num;
}
}
$total=$one+$two+$thr;
print A"$total";
こういうことではないのですか?
これでは0になってしまったのですが
0283nobodyさん
2009/11/28(土) 15:30:00ID:???0287nobodyさん
2009/11/28(土) 15:41:19ID:BdimRB/2>>271
初心者スレとはいえ、最低限の文法をググるか本読んだ方がいい
サンプルコードたくさん落ちてるじゃん
ファイルへの書き込みがopen my $wfh, ">", "a.txt"ってのと同じように
読み込みはopen my $rfh, "<", "b.txt"だよ
0288nobodyさん
2009/11/28(土) 15:45:27ID:???open FH, "<hoge.txt";
foreach(my $line = <FH>){ … }
close FH;
入門書読んだ?
0289nobodyさん
2009/11/28(土) 15:47:29ID:???foreach → while
@hoge = <FH>;
でも入力は取れる
0290nobodyさん
2009/11/28(土) 16:18:26ID:???あとレファレンスとか見てもどこに載っているのかわからないので…
0291281
2009/11/28(土) 18:03:02ID:???ファイルハンドルはファイルの名前の事だよ
普通はファイルの入出力のところに載ってると思うけど
0292291
2009/11/28(土) 18:04:34ID:???ファイルハンドルはファイルを識別するための任意の文字列の事だよ
でした
0294nobodyさん
2009/11/28(土) 18:15:00ID:???0295293
2009/11/28(土) 18:16:33ID:???0296nobodyさん
2009/11/28(土) 21:24:20ID:???こういうことではないんですか?
open(A,">a.txt");
my($one, $two, $thr) = (0, 0, 0);
open FH, "<b.txt";
foreach(my $line = <FH>)
{
if( $num >= $one)
{
$two=$one;
$thr=$two;
$one=$num;
}elsif( $num >= $two )
{
$thr=$two;
$two=$num;
}elsif( $num >= $thr )
{
$thr=$num;
}
}
$total=$one+$two+$thr;
print A"$total";
0297296
2009/11/28(土) 21:38:36ID:???追加 -> close FH;
0298296
2009/11/28(土) 22:12:32ID:???use warnings;
open(A,">a.txt");
my($one, $two, $thr) = (0, 0, 0);
open FH, "<b.txt";
foreach my $num (<FH>)
{
if( $num >= $one)
{
$two=$one;
$thr=$two;
$one=$num;
}elsif( $num >= $two )
{
$thr=$two;
$two=$num;
}elsif( $num >= $thr )
{
$thr=$num;
}
}
my $total = $one + $two + $thr;
close FH;
print A"$total";
これで何とかできているようです。が、
argument "\n" isn't numeric in numeric gt at 〜.pl line8, <FH> line8.
と出るのは何なのでしょう
あと、一行ごと読みこむ場合は分かったのですが、
http://www.ioi-jp.org/joi/2008/2009-yo-prob_and_sol/2009-yo-t1/2009-yo-t1.html
のような場合はどうやって読み込むのでしょう
0299nobodyさん
2009/11/28(土) 22:25:29ID:???0300296
2009/11/28(土) 22:32:47ID:???いえ、別にそういうわけではありません。
とりあえず、読み込み方は自分には見つからなかったので、教わりたいなと思ったので…
すいません
0301nobodyさん
2009/11/28(土) 22:34:31ID:???perlだとこんなに短く書けるよということで面白い。本人が理解できなきゃ意味ないか。
>>298
foreach my $num (<FH>) はやめれ。これだとファイルの中身をすべてメモリに読み込むので、
今回はいいけど、このファイルが数百万行あったらどうする。普段から
while (my $num = <FH>) {
chomp $num; # 各行のデータには改行コードがくっついたままなので取り除く
# 処理
}
としておくのが吉。
argument "\n" isn't numeric in numeric gt at 〜.pl line8, <FH> line8.
は、改行コードがくっついている値を数値比較したから。
こういうのもuse warningsを付けているから出るわけです。
> http://www.ioi-jp.org/joi/2008/2009-yo-prob_and_sol/2009-yo-t1/2009-yo-t1.html
> のような場合はどうやって読み込むのでしょう
結局何もかも分からないわけですね。
いくら初心者スレとはいっても、少しはわかるようになるまで学習してから取り組んだらいかが。
0302301
2009/11/28(土) 22:42:45ID:???>>298
のコードだと、2つの大学全体の上位3つの合計になってしまうよ。問題の要件を満たしていない。
あと、普通こういうので入力/出力といったら標準入力/標準出力ではないかと思います。
その点でも>>273は満たしてくれている。
0303nobodyさん
2009/11/29(日) 00:50:13ID:???新鮮だなぁ
0304nobodyさん
2009/11/29(日) 01:42:21ID:1LHj/rCz学校で習ってすぐの覚えたてで何か問題解こうとここに聞きにくるのとかポジティブだよねw
最近の書き方だと下のが結構まとまってると思う。
ttp://d.hatena.ne.jp/perlcodesample/20091120/1246679588
あと、標準入力とかダイヤモンド演算子の話はもっと簡単なサンプルコードを書くところから始めた方が理解できると思う
0305nobodyさん
2009/11/29(日) 10:19:40ID:???こういう処理したいんだけど、読んだ本だといまいちわかりません」
というレベルじゃないのか?
文法すら知らないのは初心者ではなく教えてちゃんだ。
0306nobodyさん
2009/11/29(日) 10:40:54ID:???「最近の書き方」じゃねーよ、単なる個人の趣味じゃねえか
悪くは無いが。
で、ここの最近のレスも合せてどうしても突っ込みたくなったから書くが、
× while( my $line = <FH> ){}
◯ while( defined ( my $line = <FH>) ){}
perldoc perlsyn にも書かれてる。
0307nobodyさん
2009/11/29(日) 11:07:16ID:???「リンク先の内容が、リンク先の書いた奴の」って意味ね。
0308296
2009/11/29(日) 11:57:19ID:???で、朝
http://books.yahoo.co.jp/book_detail/AAY78372/
この本を買って今読んでいるのですが、read関数の使い方がよく分かりません
どなたか教えていただけないでしょうか
0309nobodyさん
2009/11/29(日) 12:28:14ID:???0310nobodyさん
2009/11/29(日) 12:30:07ID:???「聞きに来る」時点で全然ポジティブでも何でもないです。
所謂「クレクレ」でしかないです。
例え「車輪の再発明」と云われても自分で調べ、自分で考えてその結果をここに書き連ねてこそポジティブっていうもんです。
世知辛いこの世の中、ただただ「速さ」だけを求められて、こういった「クレクレ君」が憚っているのが現状だと思うと悲しいんだけれどもね。。。
0314nobodyさん
2009/11/29(日) 16:11:18ID:???バイトがなんなのか理解してないの?
ここで聞く前にもっと勉強した方がいいと思うよ
検索すれば出る内容なんだから
0316nobodyさん
2009/11/29(日) 21:02:25ID:???#GCDの計算です。
print "input number 1\n";
$a = <STDIN>;
chomp($a);
print "input number 2\n";
$b = <STDIN>;
chomp($b);
$n = &gcd($a,$b);
sub gcd{
if($c != 0){
$c = $_[0] % $_[1];
$n = &gcd($gcd[1],$c);
}else{
print "G.C.D is $_[0]";
}
}
#よろしくおねがいします。
0317nobodyさん
2009/11/29(日) 21:16:37ID:???0318nobodyさん
2009/11/29(日) 21:38:42ID:???input number 1
18
input number 2
32
G.C.D is 18%
0319nobodyさん
2009/11/29(日) 21:48:48ID:aDLivjg20321nobodyさん
2009/11/29(日) 21:55:47ID:???0322nobodyさん
2009/11/29(日) 21:57:26ID:???これはひどい
0323316
2009/11/29(日) 22:02:31ID:???これも引数にしないとだめだったんですか?
$cをメインルーチンに追加して試してみましたがだめでした・・・
>>318
サブルーチンは呼び出せているのですが、ifの中身がうまく処理できずにelseの処理にうつってしまいます
GCDのアルゴリズムは
_[0]と_[1]を割って余りを$cに代入
$cが0でなければ_[1]を_[0]に、$cを_[1]に代入
$cが0になるまでこれを繰り返す
$cが0なら[0]を出力
間違ってましたかね
0325nobodyさん
2009/11/29(日) 22:11:31ID:???sub gcd {
my($a, $b) = @_;
if ($a < $b) { # $bの方が大きければ逆にする
($a, $b) = ($b, $a);
}
if ($b != 0) {
gcd($b, ($a % $b));
}
else {
print "G.C.D is $a";
}
}
$_[0]とか$_[1]を使い回さない方がいい。
色んな場所で使うなら最初に違う文字に置き換えた方が無難
$nも使わないならわざわざいらないでしょ
>>323の順番に処理して行ったらif文が割り算の前に出てくるのもおかしいよね
0326nobodyさん
2009/11/29(日) 22:15:22ID:???それ、ユークリッドの互除法になって無いぞ。
$_[0], $_[1] を使い回す方が、 $a, $b を my するよか千倍マシだ。
0327nobodyさん
2009/11/29(日) 22:21:39ID:???あれ?ちがうんだっけ。昔の記憶のまんま書いてみて答えあってたからいいかと思った
つか、普通$_[0]とか使い回すもん?
実際、何の値入ってるかわかんなくなって>>316みたいなコード書く元になるから使い回すなら置き換えた方がいいと思うんだけど。
0328nobodyさん
2009/11/29(日) 22:33:53ID:???される特殊変数だ。
それを他の場所で使うくらいなら、 @_ を使う方がましだと言っている。
my $. = 'hoge' ;
↑これをするのと同じくらい変態行為。
>>325
>if ($b != 0) {
これ常に真だが?
0329nobodyさん
2009/11/29(日) 22:40:51ID:???あぁ、なるほど。$a,$bは特殊変数で使われるんだっけ。
普段$aとか$bは使わないけど>>316のコードをなるべく生かそうと思って失敗したわ。
>>if ($b != 0) {
>これ常に真だが?
最終的に余りゼロになるでしょ?
0330nobodyさん
2009/11/29(日) 22:47:49ID:???ここまで説明しなきゃ解らんのか?
0331326
2009/11/29(日) 22:55:42ID:???0332316
2009/11/29(日) 23:06:02ID:???この程度もわからなかっただなんてしにたい
print "input number 1\n";
$a = <STDIN>;
chomp($a);
print "input number 2\n";
$b = <STDIN>;
chomp($b);
&gcd($a,$b);
sub gcd{
if($_[1]>$_[0]){
($_[1],$_[0])=($_[0],$_[1]);
}
if($_[1] != 0){
&gcd($_[1],($_[0] % $_[1]));
}
else{
print "G.C.D is $_[0]";
}
}
0333nobodyさん
2009/11/29(日) 23:23:23ID:???えっと、そう書くことになるから「$_[0]と$_[1]に何が入るかわからなくなるので、使う初めに置き換えた方がいいよ」って話ね
例えば、今回とは別の例としてそのsubが30行くらいあったとして、君が1週間後にメンテナンスするとするでしょ?
ぱっと一番下のprintを見た時に「あぁ、$_[0]だから引数の一番目の値を出力してるな」とか思っちゃうわけだけど、
その前に入れ替えやってるからそうとは限らない。
そうするとメンテする時に変数の代入をしている所を確認する作業が増えて面倒。
少なくとも「$_[番号]は引数の順番通りに入ってる」って思ってる人は多いから入れ替えとかしない方がいいよ
0334nobodyさん
2009/11/29(日) 23:28:53ID:???use strict;
をスクリプトの2行目に書くのをオススメする
変数のスコープを理解すべし
死ぬのはそれからだ
0335nobodyさん
2009/11/30(月) 00:16:25ID:???0336332
2009/11/30(月) 00:49:26ID:???サブルーチンの外で入れ替える、ということですね。気をつけます。。
>>334
わかりました。
perlは今までやってきたCやJavaと比べて書きやすいのですが、
やっぱりある程度の制約を強要したほうがエラーが起こりにくいということがよくわかりました。
■ このスレッドは過去ログ倉庫に格納されています