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/
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と比べて書きやすいのですが、
やっぱりある程度の制約を強要したほうがエラーが起こりにくいということがよくわかりました。
0337nobodyさん
2009/11/30(月) 01:26:09ID:???> サブルーチンの外で入れ替える
まあそれでも動くっちゃあ動くが違うだろ
普通に考えれば関数の先頭で
my($num1, $num2) = @_;
($num1, $num2) = ($num2, $num1) if $num2 > $num1;
などとして、以後$_[X]の代わりに$numXを使うという意味だ
0338nobodyさん
2009/11/30(月) 02:19:08ID:HMASs2oDこのクラスのオブジェクトを使用してDBIのメソッドを呼ぶとき、
$obj->dbh->prepare(@args); #データベースハンドルのゲッタを介した呼び出しではなく
$obj->prepare(@args) #こう呼びたいと思っています。
そこでAUTOLOADを定義して委譲するように書いたのですが、ここで不明な点があるのです。
sub AUTOLOAD {
my $self = shift; my @args = @_;
our $AUTOLOAD; #呼ばれたメソッドの完全修飾名
my $method_name = (split '::',$AUTOLOAD)[-1]; #メソッド名部分を切り出し
if ($self->dbh->can($method_name)) { #メソッドがDBIにあれば
return $self->dbh->$method_name(@args); #DBIのメソッド呼び出し(ここが疑問)
}
}
例のようにprepareを呼べばステートメントハンドルが返り、つまり正しく動いてるのですけど、
$method_nameは(多分)文字列なのに、どうしてメソッド呼び出しがおこなわれるのかわかりません。
経緯としては、試しに書いてみたら動いてしまい、
後追いで理屈の裏づけをとりたいと思ったら答えが見つからない、という状況です・・。
(use strict環境なのでシンボリック参照ではないですよね。)
説明つく方いましたらお願いしますm(_ _)m
0339nobodyさん
2009/11/30(月) 03:57:11ID:???0340nobodyさん
2009/11/30(月) 04:00:49ID:???0341nobodyさん
2009/11/30(月) 04:53:13ID:???気持ち悪いならこういう風に書き換えることができたはず
if (my $ref = $self->dbh->can($method_name)) {
return $ref->(@args);
}
0343338
2009/11/30(月) 07:20:28ID:HMASs2oDなるほど!ありがたいヒントをいただきました。
canはメソッドの参照を返しているんですね。こちらは納得です!
自分のケースでは次のコードで結果を得ることができました。
if (my $method_ref = $self->dbh->can($method_name)) {
my $sth = $self->dbh->$method_ref(@args);
return $sth;
}
この際>>338の疑問はなかったことにしようと思いますw
0344nobodyさん
2009/11/30(月) 09:31:48ID:???AUTOLOAD呼び出しのコストを1回だけにするのは、あんまり意味ないかな?
404 Blog Not Found:Perl Monger の質問 - AUTOLOADって他でどうやるの?
http://blog.livedoor.jp/dankogai/archives/50491359.html
if (my $method_ref = $self->dbh->can($method_name)) {
no strict 'refs';
*{$method_name} = sub { shift->dbh->$method_ref(@_) };
unshift @_, $self;
goto &$method_name;
}
0346nobodyさん
2009/11/30(月) 18:34:17ID:???自由すぎる
0347338
2009/11/30(月) 18:49:13ID:???ありがとうございます。
自分が事前に得ていたのも>>344のようなコードでした。
$AUTOLOADに渡ってきた名前のメソッドを、型グロブを使って現在のパッケージに動的に追加し
そのメソッドに処理を転送、という意味だと思うのですが、
自分もちょっと大げさだなと思って・・・
(ちなみに今、手元にオライリー本を数冊置いてるのですが、いずれも類した手法を紹介してるんです)
しかし「AUTOLOAD呼び出しを減らす」メリットには気がつきませんでした。
以降は新しいメソッドが呼ばれるから逐次AUTOLOADが呼ばれるコストが削減できるということなんですね。
(AUTOLOADはクラス階層を全部探した最後に呼ばれるから高コスト)
自分の場合はCGIなので、アクセスごとにメソッド生成がおこなわれてしまうこともあるのですが、
複数のクエリを発行する状況ではメリットあるかもしれないです。
クラスの使用状況を見ながら適宜判断してみようと思います。
CGIなら普通に、使う分だけラップしたメソッド書いとけって話もあると思いますが^^;
たいへん参考になりました!
0348nobodyさん
2009/12/02(水) 03:41:18ID:0CcBOFc0Warning が出た時点でスクリプトの実行を一時停止させるには、怪しいところを eval でトラップさせるしかないのでしょうか?
それともデバッグに役立つようなモジュールとかあるのでしょうか?
0349nobodyさん
2009/12/02(水) 06:42:16ID:???% perl -d hoge.pl
ここに色々書いてあるから見てみるといい
http://www.ibm.com/developerworks/jp/linux/library/l-pl-deb/
0351nobodyさん
2009/12/02(水) 12:21:29ID:???XPでActivePerl5.8.9を使っています。
http://perl-users.jp/articles/advent-calendar/2008/08.html
上のURLを見て、クリップボードのURL→fenrir(ランチャ)で出来たらと思い、やってみました。
#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple;
use File::Basename;
use Win32::Clipboard;
my $dir = "$ENV{'USERPROFILE'}/jpgDL";
chdir $dir;
my $clip = Win32::Clipboard();
my $url = $clip->Get();
my @contents = get($url) =~ m{<a.*?href="(http://[^"]+\.jpg)"}gi;
foreach my $jpg(@contents) {
mirror($url, basename($jpg));
}
上記URLのワンライナー通りだとうまくいくのですが、このコードではjpgは落ちてくるけど、
ファイルが壊れているようです(ファイルサイズが全て同じになっている)。
FTPみたいにバイナリ指定する方法もないようで、どうしてよいか分かりません。
このコードの何処が間違っているのでしょうか?
ご指摘お願いします。
0352nobodyさん
2009/12/02(水) 12:32:46ID:???> my @contents = get($url) =~ m{<a.*?href="(http://[^"]+\.jpg)"}gi;
これは……
0353nobodyさん
2009/12/02(水) 13:53:24ID:???Windowsのブラウザ上でコピーしたURL(my $url = $clip->Get(); )に対して
LWPのgeでコンテンツを取得しています。
・・・と書き込みながらあれこれやって1時間、自己解決致しました。
誤) mirror($url, basename($jpg));
正) mirror($jpg, basename($jpg));
jpgじゃなくてURLのhtmlを落としてました・・・orz
0354nobodyさん
2009/12/03(木) 01:29:27ID:???htmlを使い、cgiを読み込むような↓の簡単な処理をまず作りました。
※db.cgiは単体で動作確認済みで、こちらに不備があることはありません。
<html>
<body>
<form action="db.cgi" method="post">
<input type="submit" name="exec" value="データベースの表示">
</form>
</body>
</html>
ところがこれで呼び出すとcgi(上のソース上で言うdb.cgi)がうまく動作しません。
具体的に言うと、ファイルのダウンロード画面が開かれ、開くとcgiのソースが開かれてしまいます。
エラーメッセージは表示されません。
ネットでダウンロードすると出るダウンロード画面はお馴染みの物です。
このファイルを開くか、または保存しますか?
名前:db.cgi
種類:不明なファイル
発信元:
これはアパッチの環境設定面でヘマをしてしまったのでしょうか?情報少なくてすみません。
0355nobodyさん
2009/12/03(木) 02:11:50ID:???全て書け
0357nobodyさん
2009/12/03(木) 09:13:01ID:???cgiだと思われてないよ。
0358nobodyさん
2009/12/03(木) 11:50:21ID:???0359354
2009/12/03(木) 23:52:45ID:aPQfU5cAありがとうございました。
やはりApacheの設定だったようです。
詳細の原因はわかりませんでしたが、
confファイルの色々直したら表示できるようになりました。
ありがとうございました。
0360nobodyさん
2009/12/05(土) 16:36:46ID:???1 2 3
4 5 6
7 8 9
-------------------
---------------output.txt-
6
15
24
---------------
input.txt->output.txt(行ごとに三つずつある数字の和を一行ずつ表示させるプログラム)の書き方を教えてください
0361nobodyさん
2009/12/05(土) 16:51:05ID:???こんな感じかな。違ったら誰か突っ込んでくれると思う。わからないところどこ?
use strict;
use warnings;
my $input_file = shift || 'input.txt'; # 引数もしくはinput.txt
my $output_file = shift || 'output.txt'; # 引数もしくはoutput.txt
# 読み込み処理
open my $rfh, '<', $input_file or die "$!"; # ファイルの読み込み
my @results;
while (defined(my $line = <$rfh>)) { # 1行ずつ処理
chomp $line; # 改行は削除
my @nums = split /\s+/, $line; # 空白で分割
my $sum;
for my $num (@nums) {
$sum += $num;
}
push @results, $sum;
}
close $rfh;
# 書き込み処理
open my $wfh, '>', $output_file or die "$!";
for my $result (@results) {
print {$wfh} "$result\n";
}
close $wfh;
0362nobodyさん
2009/12/05(土) 17:16:59ID:???perl -alpe'$_=$F[0]+$F[1]+$F[2]' input.txt>output.txt
perl -MList::Util=sum -alpe'$_=sum@F' input.txt>output.txt
0363nobodyさん
2009/12/06(日) 04:07:59ID:gPKy+f2T4つ目が合ったら・・・
>>360
use strict;
use warnings;
open(INFH, '<', 'in.txt');
open(OUTFH, '>', 'out.txt');
while(my $line = <INFH>){
chomp $line; # 改行削除
my $sum = 0; # ゼロで初期化
map { $sum += $_ } split(/\s+/, $line); # 空白で分割し、要素を足し算
print OUTFH "$sum\n"; # 出力
}
close(OUTFH);
close(INFH);
0364nobodyさん
2009/12/06(日) 07:36:02ID:???いつも思うのですがこのwhile文の中のdefinedって必要なんですかね?
空文字が来るこってあるのでしょうか?
0366nobodyさん
2009/12/06(日) 11:00:15ID:???0が来たらどうすんだって話じゃないか?
この場面に限らず0の評価を回避するためにdefined書かなきゃいけないことが多すぎる
0367nobodyさん
2009/12/06(日) 12:45:01ID:???Perlクックブックに、以下3つの文で、下の2つには、Perlコンパイラが、definedを挿入する
ので、一番上のように丁寧に書かなくてもOKと書いてあります。
while (defined ($line = <DATAFILE>) { ・・・ }
while ($line = <DATAFILE) { ・・・ }
while (<DATAFILE>) { ・・・ }
このdefinedの挿入は、whileループでreadline、readdir、readlink呼び出しの結果を
スカラー変数に代入する場合のみに行われる。
とも書いてあります。
0368nobodyさん
2009/12/06(日) 13:30:40ID:???�d
確かに0の場合も偽でしたね。
勝手にdefinedを挿入してくれるのかー
ただベストプラクティス的には省略に頼らず、きちんと書いたほうがいいのかな。
0369nobodyさん
2009/12/06(日) 17:16:48ID:???use Data::Dumper;
print Dumper $a;
$VAR1 = [
{
'aaaaaa' => [
'1',
'2',
],
'bbbbbb' => [
'1',
'2',
]
}
];
Dumper してこのように表示されるのですが、参照がうまくできません。
0370369
2009/12/06(日) 17:19:20ID:???foreach my $key (keys %{$a}) {
print $key."¥n";
foreach my $name (@{$$a{$key}}) {
print $name."¥n";
}
}
print $key."¥n"; までは出来ていますが、そこから先が動きません。
この参照の仕方は間違っていますか?
0372nobodyさん
2009/12/06(日) 17:37:42ID:???use warnings;
my $var = [
{
'aaaaaa' => ['1', '2'],
'bbbbbb' => ['1', '2'],
}
];
for my $key (keys %{$var->[0]}) {
print "$key\n";
for my $name (@{$var->[0]{$key}}) {
print "$name\n";
}
}
やりたいことがわからないが、>>369の $VAR1 の内容を表示するコード
0373369
2009/12/06(日) 17:46:07ID:???$a->[0]
->[0] だったのか('A`)
リファレンスがまだよく分からない。
>>372
データの集計をしようとしてたのですが、いきなり詰まってました。
有難うございました。
0375nobodyさん
2009/12/07(月) 05:08:40ID:B0UFMTWM@{$a->[0]->{'aaaaaa'}} で配列取得でける
0376nobodyさん
2009/12/12(土) 16:38:26ID:???ありがとうございます
my @nums = split /\s+/, $line; # 空白で分割
この部分が分かりませんでした
0377nobodyさん
2009/12/12(土) 18:06:22ID:aQyC+qGS\s で分割した結果を @nums に入れてるだけ。
基本中の基本なので、これぐらいは見て分からないと・・・
0378nobodyさん
2009/12/12(土) 21:38:30ID:???続いて質問で申し訳ないのですが、
----------input.txt-
1 2 3
4 5 6
7 8 9
-------------------
---------------output.txt-
左上の数字は1です
中上の数字は2です
・
・
・
---------------
input.txt->output.txtのようなprogramの書き方を教えてください
できれば、input.txtを空白で区切った値をそれぞれ$a_1,$a_2といった変数にしてしまいたいのですが
0379nobodyさん
2009/12/12(土) 22:10:49ID:???perl -aln0e "print qq{$_の数字は$F[$i++]です}for qw(左上 中上 右上 中段左 真ん中 中段右 左下 中下 右下)" input.txt>output.txt
0381nobodyさん
2009/12/13(日) 06:32:28ID:tGb7lH/N0382nobodyさん
2009/12/13(日) 06:52:19ID:???大きなお世話なのはわかっているが言わせてくれ。
君はどうしてその学部に進もうと思ったんだい?
そういうことを勉強したくて行ったんじゃないのかい?
その宿題の解を提出して「よし、じゃあなぜそのアプローチを取ったのか説明してくれ」
と教授に求められたら「2chで出来る人達が勧めてくれました」と答えるのかい?
答えを貰うならば次に、同じような問題を目の前で10分以内に解け、
と言われてもまったく出来ないままだぞ。
君自身はいいのか、それで?
夏休みの読書感想文をコピペサイトからコピーして提出する小学生と同じだぞ。
そして変数名をデータに依存するのは間違ったアプローチだ。
他の入力データを持ってこられたらもう動かなくなる可能性がある。
0383nobodyさん
2009/12/13(日) 07:26:08ID:???eval("\$a_$_ = $_") foreach split /\s+/, $line;
if ($a_1 == 1) {...
elsif ($a_2 == 2) {...
正気の沙汰とは思えない
use strict できないし
やるんだったら
$hash{$_} = 1 foreach split /\s+/, $line;
if (defined $hash{1}) {...
elsif (defined $hash{2}) {...
0386nobodyさん
2009/12/13(日) 16:26:55ID:???初心者を免罪符にして甘えるより、いっぱい見本がWEBが転がっているんだから、
そのソース見て学んだ方がいいよ。自分の為に。
0387nobodyさん
2009/12/13(日) 17:13:31ID:???KENT 時代の見本とか要らないです><
0388nobodyさん
2009/12/13(日) 17:33:29ID:???0389nobodyさん
2009/12/13(日) 17:40:38ID:???3×3の行列みたいな感じだからこんなのがいいんじゃないかなー
my @matrix;
open my $in, "input.txt" or die $!;
while (<$in>) {
push @matrix, [split];
}
close $in;
my @pos = (
[qw(左上 中上 右上)],
[qw(中段左 真ん中 中段右)],
[qw(左下 中下 右下)],
);
open my $out, ">output.txt" or die $!;
for my $i (0..$#matrix) {
for my $j (0..$#{$matrix[0]}) {
print {$out} "$pos[$i][$j]の数字は$matrix[$i][$j]です\n";
}
}
close $out;
0390nobodyさん
2009/12/13(日) 20:13:53ID:tGb7lH/N0391nobodyさん
2009/12/14(月) 06:14:02ID:???4桁目がきたときには日本語でどうやって表現すんの?
「もっと右」?
4行目がきたときには日本語でどうやって表現すんの?
「もっと下」?
問題文も読めないの?バカなの?
0392nobodyさん
2009/12/14(月) 08:15:42ID:???0393nobodyさん
2009/12/14(月) 16:20:18ID:???[qw(左上 中上 右上)],
[qw(左中 真中 右中)],
[qw(左下 中下 右下)],
);
open my $in, "input.txt" or die $!;
open my $out, ">output.txt" or die $!;
foreach my $p (@pos){
my @s = split(/\s+/, <$in>);
foreach(0..$#{$p}){
print $out "$p->[$_]の数字は$s[$_]です\n";
}
}
close $out;
close $in;
素直に書く。
0394nobodyさん
2009/12/23(水) 12:34:01ID:???あるファイルの容量を表示するのに、現在はこのように書いてます
my $size = -s('data.dat');
$size = sprintf('%.1fKB', $size / 1024);
これをもう少しスマートに書きたいと思っているんですが、どのような
書き方がありますか?
一応以下のようにしてみたんですが、use warningsさんに怒られて
しまいました
my $size = sprintf('%.1fKB', -s('data.dat') / 1024);
0395361
2009/12/23(水) 13:25:55ID:???-sの外側に括弧付けても怒られる?何てメッセージ出るの?
use strict;
use warnings;
warn sprintf('%.1fKB', (-s 'data.dat') / 1024);
これでメッセージでなかったけど。
0398nobodyさん
2009/12/24(木) 10:25:12ID:???標準偏差を出す計算が、自分で書いた方がモジュール使う倍くらい速かったので、
モジュールは呼び出す分遅いのか、自分は計算にforeach使ってモジュール内部ではwhileだからなのだろうか、
とか思って、コードを見てみようとC\:Perl\libを漁ってみたのですが、見つからず・・・
このままだとコーディングの話ではないので取ってつけますが、
平均を出す処理 → その値を使って標準偏差の計算と、2回ループを回していたのですが、
(そんな泥臭い方法でモジュールを使う倍速なので驚いていたのです)
もう少し洗練された書き方があれば教えてください。
my $sum1;
my $sum2;
my $number = @data;
foreach my $i(@data) {
$sum1 += $i;
}
my $avg = $sum / $number;
foreach my $i(@data) { #ここがいかにも胡散臭い・・・
$sum2 += ($i - $avg)**2;
}
my $stddev = sqrt( $v / $number );
0401nobodyさん
2009/12/24(木) 15:08:02ID:Kh9UPbn8こんな式じゃなかったっけ?
foreach my $i(@data) {
$sum1 += $i;
$sum2 += ($i)**2;
}
my $stddev = sqrt( ($sum2-$number*$sum**2)/ $number );
0402nobodyさん
2009/12/24(木) 18:32:09ID:???そりゃ遅いわ…。って呟くだけなのもなんなので。
見栄えが良いってんなら、
use List::Util qw( sum ) ;
my @ddata = ... ;
my $avg = ( sum @data ) / @data ;
my $stddev = sqrt ( ( sum map{ ( $_ - $avg )**2 } @data ) / @data ) ;
0403nobodyさん
2009/12/24(木) 19:27:27ID:???遅くないんじゃないかなぁ。
0404nobodyさん
2009/12/24(木) 19:41:39ID:???の
*{"$pkg\::oh"}
なんですけど、
1. グロブを使う理由(右辺が関数リファレンスだから$でいいんじゃ。。。)
2. ここの中括弧の意味(ハッシュでもブロックでもないような。。。)
3. なんで:の前にバックスラッシュが必要?
この三点を教えてもらえないでしょうか?
0405nobodyさん
2009/12/24(木) 20:47:12ID:pZAKTGQQ等差数列{a_n}は公差が正であり、その全ての項がSの要素である。
{a_n}の初項でないある項が2010のとき、{a_n}の個数の最大値が存在するならばそれを求めよ
この問題を解くために次のようなprogramを考えました
何がいけないのでしょうか
http://www1.axfc.net/uploader/Sc/so/66961
拡張子は適当に変更をお願いします
0406nobodyさん
2009/12/24(木) 21:56:51ID:???0407nobodyさん
2009/12/24(木) 22:11:33ID:???お前に指導するまえに言っておきたいことがある
かなり厳しい話もするが、俺の本音を聞いておけ
俺より先に投げてはいけない
俺より後に曲げてもいけない
バグはうまくとっぱらえ、いつもきれいに書け
できる範囲で構わないから
忘れてくれるな、デバッグもできない男に
このスレを守ることなどできないことを
お前にはお前にしかできないこともあるから
それ以外は口出しせず、黙って俺についてこい
お前の技術と俺の技術、どちらも同じだ大切にしろ
小技、大技、賢くこなせ
たやすいはずだ愛すればいい
人の陰口は言うな聞くな
それからつまらぬ嫉妬はするな
その方法はある
たぶんあると思う
あるんじゃないかな
ま、ちょっと覚悟はしておけ
スクリプトはみんなで育てるもので
誰かが苦労して
つくろうものではないはず
お前はこのスレへ、恥を忍んでくるのだから
帰る場所などないと思え
これからこのスレがお前の家
0408nobodyさん
2009/12/24(木) 22:16:57ID:???1. 実行時に名前空間$pkgに関数ohを作るためにグロブを使う。この関数ohはlocalしてるのでrunを抜けた時点で破棄される。
2. runはプロトタイプrun(&)で宣言されてるので、これは関数のリファレンスを渡したものとして扱われる。
すなわちrun(sub { oh() })
3. $pkg::ohだとpkg名前空間の$ohという変数になってしまう。*{$pkg . '::oh'}と等価。
0409nobodyさん
2009/12/24(木) 22:53:34ID:???御回答ありがとうございます。
1.については自分がグロブをよく分かっていないことが分かりましたので勉強します。
2.については自分の質問の仕方がまずかったのかよく分かりません。
もう少し自分で考えてみます。
3.についてはすっきりしました。こんなテクがあるんですね。。。
0410nobodyさん
2009/12/24(木) 23:23:20ID:???*{"$pkg\::oh"}の中括弧はこの括弧でくくった範囲が識別子ですよ、ってこと。
0411nobodyさん
2009/12/25(金) 12:15:55ID:???中括弧にはそういう使い方もあるのですね。
perlは文法項目がたくさんあって覚えるのが大変ですが、
がんばって勉強したいと思います。
御回答ありがとうございました。
0412nobodyさん
2009/12/25(金) 12:53:54ID:???パッケージ変数(グローバル変数)には色々な型がありますが(スカラー$、配列@、ハッシュ%等)、
それらはグロブを経由して格納されています。
例えば、以下のように様々な型の同名変数が宣言されたとします。
$foo = "hoge";
@foo = ("hoge", "fuga");
%foo = (hoge => 1, fuga => 2);
sub foo { print "hoge" }
このとき、グロブ*fooには、下図に示すように、SCALAR、ARRAY、HASH、CODE・・・(他にもあります)
という場所に、各型に対する実体へのリファレンス(ポインタ)が格納されており、これをスロットと
呼びます。
┏━━━━━━━━━┓
┃ ┌────┐.┃$foo
┃ │SCALAR ┿╋━━→ "hoge"
┃ ├────┤.┃@foo
┃グロブ│ ARRAY ..┿╋━━→ ("hoge", "fuga")
┃*foo .├────┤.┃%foo
┃ │. HASH ┿╋━━→ (hoge => 1, fuga => 2)
┃ ├────┤.┃&foo
┃ │. CODE ┿╋━━→ sub { print "hoge" }
┃ └────┘.┃
┗━━━━━━━━━┛
0413412
2009/12/25(金) 12:54:42ID:???*foo{SCALAR}
*foo{ARRAY}
*foo{HASH}
*foo{CODE}
と型を中括弧で囲んでアクセスできます。
スロットには各変数のリファレンスが格納されているので、実体にアクセスするにはデリファレンス
(リファレンス先の実体を見ること)する必要があります。
例えば、$fooの実体にアクセスするには、
print ${ *foo{SCALAR} }; #=> hoge
とします。
デリファレンスは、リファレンスを中括弧で囲み、適切な型識別子(この場合$)を前に付けます。
このように、実際のアドレス値が格納されているリファレンス(ポインタ)をハードリファレンスと
もいいます。
これに対して、文字列を変数名として認識するシンボリックリファレンス(ソフトリファレンス)
というのもあります。
print ${ "foo" }; #=> hoge
同じく中括弧で囲みデリファレンスします。
■ このスレッドは過去ログ倉庫に格納されています