トップページ⇒tech
1001コメント376KB

Perlについての質問箱 25箱目

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/06/02(金) 23:43:29
"The duct tape of the Internet" こと、Perlについての質問箱です。
"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/06/02現在の最新版: 5.8.8
● 2006/06/02現在の開発版: 5.9.3

リンク集は>>2-3
過去スレは>>4
0153デフォルトの名無しさん2006/06/06(火) 19:57:51
OSによる行バッファリングが入っちゃうからじゃないかな
0154デフォルトの名無しさん2006/06/06(火) 23:30:32
>>152
Perlでは一文字づつ処理しなければならないケースが極端に少ないため、
C的な感覚でのgetc()の使用は、ほとんどの場合もっとずっと簡単な正規表現での処理に置き換えられる。
したがって、getc()でなければならないという強い確信があるとき以外は使わないほうがいい。

という程度のことだと思うよ。
実際、俺は使ったことないし、使ってるコードを見たこともない。
01551522006/06/07(水) 07:28:51
>>153どうもです。行バッファリングって具体的にどういう?

>>154さんくすです。ということは行バッファリングどうこうって関係ないのね。
0156デフォルトの名無しさん2006/06/07(水) 15:07:19
>>155
まあ落ち着け。
入力ストリームから一文字入ってくるたびに何か処理を行いたいのに、一行分貯まるまで渡ってこないと困るケースがあるとは考えないか?
0157デフォルトの名無しさん2006/06/07(水) 16:30:13
while (my $oee = <$fh>) {

}

これってループ毎に$oeeはいちいちmy宣言されてしまうから

my $oee;
while ($oee = <$fh>) {

}

とした方がいいですか?
0158デフォルトの名無しさん2006/06/07(水) 16:35:47
>>156
そんなケースってあるの?
例示してくれ
0159デフォルトの名無しさん2006/06/07(水) 16:46:37
parでつくったguiあぷり。

コンパイルしたディレクトリだとアイコンが表示されるけど、
違うディレクトリに移動するとアイコンが表示されない。
(ファイル自体のアイコンだけは問題ない!)

他の部分は、ウィンドウズのアイコンになる。
IconResetで内部無理矢理変えても駄目だなあ。

なんで?
0160デフォルトの名無しさん2006/06/07(水) 18:30:56
>>157
とても古いperlを使うなら Yes
そうでないなら、廃人にとっては Yes かもしれないが、通常は No

例えば、整数値のみを保持しているスカラ変数を文字列中で展開すると
整数値以外に文字列値も持ったり、数値演算を行うとdouble値も持ったり
する事を気にするような場合は Yes かもしれない。

後は、こんな...
perl -e "while(my $x=<STDIN>) {printf '%08x %3d %3d',unpack('lll',unpack('P12',unpack('P4',pack('l',\$x))));}"
真似が普通の人にとっても Yes かも

my(やlocal)の実行時効果は
・ブロック内で最初の実行
  ブロックから抜ける時の変数回復情報に、変数情報と変数実体を登録する
  新しい変数実体を確保・初期化する
・それ以外
  古い実体のリファレンスカウントを減らす
  (リファレンスカウントが0になったら開放される)
  新しい変数実体を確保・初期化する
  (高い確率で同じ実体が再利用される)
だから、負荷自体はかかるけどね。

大雑把に、ループ中のmy(やlocal)は「my変数はlocal変数より速い」と同じ
程度の差でしかないから、読みやすさを優先した方がいい。
0161デフォルトの名無しさん2006/06/07(水) 20:00:58
>>158
そう来たか。w いや、なんでも疑問を持ってみるのはいいことだ。
ひとつ最も端的な例を挙げるとするなら、端末からのユーザ入力ということになる。

# 普段の I/O でバッファリングなどを意識しなくていいというのは言語の成果なんだろうね。
# 十年後にはこういう話題の価値ってなくなってるんだろうなあ。うん、そのほうがいい。
0162デフォルトの名無しさん2006/06/07(水) 20:53:11
perlでインタラクティブなことをするのってバカらしいしな。
というかコンソールツールで。
0163デフォルトの名無しさん2006/06/07(水) 21:09:08
昔、Term::Readline 入れて作らされたなあ。
自分のためのスクリプトだったらそんなことしないのに。
0164デフォルトの名無しさん2006/06/07(水) 22:59:03
getcは便利だよ
0165デフォルトの名無しさん2006/06/07(水) 23:09:10
>>164
大丈夫だ。そこは誰も否定してない。w
移植性や保守性、実行時効率などを考慮すると、いろいろ面倒だから気をつけれ、という話だ。
0166デフォルトの名無しさん2006/06/08(木) 11:45:01
if ( $isDoorOpen ) {
   goUp($MAX);
}
0167デフォルトの名無しさん2006/06/09(金) 12:19:18
$height += 100 unless int rand 10;
0168デフォルトの名無しさん2006/06/09(金) 18:50:27
Win32::API
について質問です。
Win32::APIで呼び出せるdllの呼び出し規約は何なのでしょうか?
0169デフォルトの名無しさん2006/06/09(金) 19:29:36
現在時刻をミリ秒まで拾える方法があれば教えてください。
0170デフォルトの名無しさん2006/06/09(金) 19:34:43
Time::HiRes
0171デフォルトの名無しさん2006/06/09(金) 20:42:08
>>168
WINAPI
01721682006/06/10(土) 00:30:10
>>171
ありがとうございます。
WINAPI = stdcallであることを確認できました.
0173デフォルトの名無しさん2006/06/10(土) 01:38:31
最近perlの本買って勉強し始めたんだけど
買った本に載ってた問題で「うるう年の判定スクリプトをif文の入れ子の形で書け」
ってのがあって

print "year = ?";
chomp($year = <STDIN>);

if ($year % 400 == 0){
print "uruu doshi desu\n"
} else {
if ($year % 4 == 0){
if ($year % 100 != 0){
print "uruu doshi desu\n"
} else {
print "hei nen desu\n";
}
こう書いて実行したんだけどエラーが出て動いてくれません。
エラー内容を見てみると、最後の行がまずいらしいんですけど
どう弄れば動いてくれるようになるのかさっぱり・・・
0174デフォルトの名無しさん2006/06/10(土) 01:39:45
; 付け忘れだ
0175デフォルトの名無しさん2006/06/10(土) 01:56:27
>>173
} が最後に1つ足りない。
01761732006/06/10(土) 02:07:33
動きました。
}の数が足りなかったのですね。
ご教授ありがとうございました。
0177デフォルトの名無しさん2006/06/10(土) 03:16:30
my $flag = ( $year % 4 == 0 and $year % 100 != 0 or $year % 400 == 0 );
print qw( 平年 閏年 )[$flag] , "です";

って書いたあとにifを使う問題だと気付く・・・
my $mes = "平年です";
$mes = "閏年です" if $year % 4 == 0 and $year % 100 != 0 or $year % 400 == 0;
print $mes;

たぶん、問題からすると外れ・・・
0178デフォルトの名無しさん2006/06/10(土) 04:21:00
ところで>>173見てて思ったんですけど、対応したカッコ({})に
正しくマッチする正規表現て作れるんですか?
0179デフォルトの名無しさん2006/06/10(土) 04:43:49
perl初めたてであほな質問かもしれないのですが、、

$lineに

<a href="http://***.com/abc/"; target="_blank">keyword</a> | <a href="http://***.com/def/"; target="_blank">hoge</a>


が格納されているときに、前半のURLだけを取得したくて

$line =~ m/href=['"'](.*)['"'](.*)keyword(.*)/i;
print "match : $1 \n";

のような正規表現を書いてみたのですが、$1には
http://***.com/abc/"; target="_blank
がマッチングしてしまいます。
これはどこが間違ってるのでしょうか?
01801792006/06/10(土) 04:46:24
" → ダブルクォーテーション

ですorz
01811792006/06/10(土) 04:48:36
あれ、なんか2chのhtmlタグ変換ルールがよくわからん(´A`)
0182デフォルトの名無しさん2006/06/10(土) 06:04:55
>>178
再帰的なパターン(??{ code })を使用
ttp://www.din.or.jp/~ohzaki/regex.htm#GetNestedParen

>>179
条件がわからんのでどの程度の答えを出せば良いのか迷うけれど、
keywordの場所は初めとは決まってなくて、かつ
keywordは行に一つしか出てこない前提での回答。
my $line = q{<a href="http://example.com/abc/"; target="_blank">keyword</a> | <a href="http://example.com/fuga/"; target="_blank">fuga</a>};
$line =~ m/
.* # 二番目になることもあるかもしれないので余分を喰わせる
href=(['"])(.*?)\1 # \1 = (['"])の部分でマッチした方
.*? # target="_blank">
keyword/ix;
print "match : $2 \n";
ともかく重要なのはバックトラックを行わないようにした変更.* -> .*?
0183ヽ(´ー`)ノ ◆.ogCuANUcE 2006/06/10(土) 08:40:20
>>178
Regexp::Common::balenced とか。
中で使ってる原理は >>182 と同じだけどね。
0184デフォルトの名無しさん2006/06/10(土) 17:59:33
$rand = int(rand(6));
if($rand == 0)
{
$a = "YES_00";
}
elsif($rand == 1)
{
$a = "YES_01";
}
elsif($rand == 2)
{
$a = "YES_02";
}
elsif($rand == 3)
{
$a = "YES_03";
}
else
{
$a = "NO";
}

という処理をある条件下で判定させているのですが
1回目の判定が

YES_00

だった際に2回目の判定は「YES_00」以外にしたいのですが
どのようにしたらいいのでしょうか?
まだまだはじめたばかりなのでアドバイスいただければと思います。
0185デフォルトの名無しさん2006/06/10(土) 18:13:57
やりたいことがわからん。
判定がYESってなんだよ。判定は$randでやってるじゃねーか。

一回目の判定が $rand == 0 だったときという意味か?
で、そのとき何をするって?
0186デフォルトの名無しさん2006/06/10(土) 18:20:41
2回続けて同じ値にしたくないということだろうね。
例えば、0が出た後は、0以外の値が出るまで乱数を発生させたいとか。
0187デフォルトの名無しさん2006/06/10(土) 18:21:45
数字が全角になってた。。orz
0 ⇒ 0
0188デフォルトの名無しさん2006/06/10(土) 18:32:23
>>184
配列に0から6まで入れてシャッフルしてみれば?
01891842006/06/10(土) 18:49:30
申し訳ないです。
>>186さんの言うとおりです。
質問内容おかして混乱させてしまいまして申し訳ありません。
0190デフォルトの名無しさん2006/06/10(土) 19:02:28
>>184
do{
  $rand = int rand(6);
}while($a eq 'YES_00' and  $rand==0);

if($rand <=3 ){
  $a = 'YES_0' . $rand;
}else{
  $a = 'NO';
}
01911792006/06/10(土) 19:18:23
>>182
まさかここまで丁寧に答えてくれるとは、、ありがとうございました。
おかげさまでうまくいきました
にしてもPerlの正規表現は便利ですねぇ
0192デフォルトの名無しさん2006/06/10(土) 19:18:55
open (DAT,"<sample.txt");
@file = <DAT>;
close (DAT);
%hash;
for $i (@file){
@test = split(/[ ,\n,.,\",_,\=,;,:,(,),\',-]/,$i);
for $i (@test){
$i =~ tr/A-Z/a-z/;
$hash{"$i"} += 1;
}
}
foreach $word (sort {$hash{$b} <=> $hash{$a}} keys %hash){
print "$word $hash{$word}\n";
}

このプログラムでsample.txt内の単語の数をソートして表示するプログラムをつくっているのですが、結果に

367
the 214
in 63
is 60
of 56
and 38
god 33
to 32
that 31
…
というように「 367」という謎の単語を表示してしまいます。
どうもsplitで記号を消去するときにでてきてしまうらしいのですが、、、どうすればこの謎の記号を%hashに登録しないようできるでしょうか?数が300以上の単語は表示しないなんてプログラムではだめだと思うのでなんとかしたいです。
よろしくお願いします。
0193デフォルトの名無しさん2006/06/10(土) 19:19:16
my @a = (0..5);

while(@a) {
  my $rand = splice @a, int(rand(scalar @a)), 1;
  print "$rand\n";
}

こういう事じゃね?
0194デフォルトの名無しさん2006/06/10(土) 19:24:03
>>193 は >>184 の返信で

>>192
1つ勘違いしてると思うけど
@test = split(/[ ,\n,.,\",_,\=,;,:,(,),\',-]/,$i);
じゃなくて
@test = split(/[ \n.\"_\=;:()\'-]/,$i);
でおk

@file から一行取り出した時に最後に改行がついているので
"AAA BBB CCC\n"
この改行を chomp で取り除いてから split すれば多分大丈夫
0195デフォルトの名無しさんNGNG
もう…終わりだね…
0196デフォルトの名無しさん2006/06/10(土) 19:28:53
>>192
空白とか(splitの対象文字)が367個入ってるということでは?
あと split で、なんでカンマを入れてるの?
カンマで区切るんじゃないけど…。
0197デフォルトの名無しさん2006/06/10(土) 19:34:09
つか
@test = split(/\W+/,$i);
でよくね?

んで全部ハッシュに入れ終わったら
delete $hash{""};
とか。
0198デフォルトの名無しさん2006/06/10(土) 19:37:44
♪なーつのおーわーどぅぃー
01991842006/06/10(土) 19:39:06
みなさんレスありがとうございます。
まだまだ未熟ですが勉強していきたいと思います。
ありがとうございました。
02001922006/06/10(土) 20:25:28
皆さんありがとうございました!!
おかげで意味がわかんないあの367はきえました(T-T )( T-T)ウルウル

あっざーっした!!
0201デフォルトの名無しさん2006/06/10(土) 22:09:33
>>199
>>200
頼むから二度と来ないでね。
0202デフォルトの名無しさん2006/06/10(土) 22:57:25
>>199
かわいそうに。
初心者の俺が作ったのを使ってみて。

$zenkai = "NO" if(!defined $zenkai); # $zenkai変数がなければ作る。とりあえず"NO"を代入

do {
$rand = int(rand(6));
if($rand < 4) {
$a = sprintf("YES_%02d",$rand)
} else {
$a = "NO";
}
} while($a eq $zenkai); # 前回と比較して同じなら繰り返す

$zenkai = $a; # 今のを前回のとして保存する
0203デフォルトの名無しさん2006/06/11(日) 03:26:31
相対パス ./index.html を
絶対パス http://domain.com/index.html に置換したくて

$domain = "http://domain.com/";;
$tmp =~ s/'./'/$domain/i;

のようなスクリプトを書いてみたのですが、 ./ の部分でエラーがでてしまいます。

./ はどのように記述すればいいのでしょうか?
0204デフォルトの名無しさん2006/06/11(日) 03:36:28
\.\/
もしくは区切り文字を変えて
s|\./|$domain|;
0205デフォルトの名無しさん2006/06/11(日) 03:43:15
>>204
おぉ、なるほど区切り文字って使い分けていいんですねぇ
ありがとうございましたっ
0206デフォルトの名無しさん2006/06/11(日) 04:20:56
いらんお世話かもしらんけど、
s( )( )
s[ ][ ]
s{ }{ }
s{ }( )
とかも可能.

あと、区切り文字と同じ文字を正規表現内で使う時は \ でっせ
クウォートしても意味なっしんぐ
0207デフォルトの名無しさん2006/06/11(日) 04:49:46
なるほど、いくつかパターンがあって都合のいいやつを選べばいいってことか

ついでに、もう一つ質問なんですが

$data =~ m/.*($key1|$key2|$key3)(.*?)/i

みたいな感じで、いくつかのキーワードを含む物とマッチングしたい場合
keyが増えたときに、めんどくさいことになりますよね。

ここのkeyを配列@keyにいれて

$data =~ m/.*(@key)(.*?)/i 

みたいな感じで、@keyの要素のどれかとマッチングを取るようにしたいんですが
なにかスマートな書き方ってないでしょうか

みたいにやりたいんですが、
02082032006/06/11(日) 04:51:30
最後の行の

「みたいにやりたいんですが、」

は無視してください・・・
0209デフォルトの名無しさん2006/06/11(日) 05:11:04
スマートかどうかは知らんけど、俺は正規表現を複雑にするよりforeachする。
foreach my $key (@array){
  m/.*($key)(.*?)/i
}
0210ヽ(´ー`)ノ ◆.ogCuANUcE 2006/06/11(日) 05:40:59
うーん、こうか?

$data =~ m/((??{ join('|', @key) }))(,*?)/i;
0211デフォルトの名無しさん2006/06/11(日) 13:28:49
>>209 のほうが好み。読みやすく、また通常は処理が速い。
用途にもよるけど気分的には \Q$key\E しておきたいところ。
02122032006/06/11(日) 14:46:22
>>209-210
レスありがとうございます。
同じ処理が2カ所にあるんで、可読性があれになりますが
勉強ってことで両方使ってみようと思います(`・ω・´)
0213デフォルトの名無しさん2006/06/11(日) 15:02:07
>>212
> 同じ処理が2カ所にあるんで、可読性があれになりますが

関 数 に 括 り 出 せ
0214デフォルトの名無しさん2006/06/11(日) 15:27:01
展開は出来ても因数分解は出来ないってあれか?
0215デフォルトの名無しさん2006/06/11(日) 16:01:46
俺Perl使い始めて10年近くなる事に気付いたけど、
こんな複雑な事やった事ない…。orz
0216デフォルトの名無しさん2006/06/11(日) 18:22:17
「Perlオブジェクト、リファレンス、モジュール」
という本のクロージャという項目に書かれていた
内容について質問です
ちょっと長くなりますがお許し下さい
引用----------------------------------------
use File::Find;
my $total_size = 0;
find(sub { $total_size += -s if -f }, "."};
print $total_size, "\n";

この無名サブルーチンが変数$total_sizeにアクセス
している点に注目して下さい。変数$total_sizeが無名
サブルーチンのスコープの外部で宣言されているにも
かかわらず、この無名サブルーチンは変数にアクセス
しています。つまり、findから呼び出されたコールバック
サブルーチンは、「「「本来なら直接アクセスできない変数
にアクセスでき」」」、さらにその変数の値を更新することが
できるのです。
---------------------------------------------------

「「「」」」で囲んだところが理解できません。
たとえば
my $value = 10;
function();
sub function {
  print $value;
}
このコードはちゃんと10と表示されます。サブルーチン内から
サブルーチン外で宣言された変数には直接アクセスできます。
なのに本では「本来なら直接アクセスできない変数」と書かれ
ています。どういうことなのでしょうか?
0217デフォルトの名無しさん2006/06/11(日) 18:31:11
>>216
その比較した例は適切では無いね
{
  my $value = 10;
  function();
}
sub function {
  print $value;
}
こう。$valueは上にあるブロック(=本の例ではファイルのスコープに相当)内でスコープが完結している。
対してfunctionサブルーチンはFile::Findモジュールにあるから、そのスコープからは$valueは見えない。
レキシカル変数については、そのスコープの範囲とか理解してる?
0218デフォルトの名無しさん2006/06/11(日) 18:44:31
>>216
無名サブルーチンを定義した際、同じスコープにある変数は
無名サブルーチンからはグローバルに見える。
本来外側にあって見えないはずの my $total_size が
無名サブルーチンからも見える、ということ。
言葉で説明するのむずいな。
02192162006/06/11(日) 18:49:19
>>217
を読んで
「理解できました。まじありがとうございます・・・」
と思っていたら
>>218
を読んでもう何もわからなくなりました
02202162006/06/11(日) 18:50:08
>>217さんと>>218さんは
言い方は違うけど同じことを言っているのですか?
0221デフォルトの名無しさん2006/06/11(日) 18:58:51
>>220
>>217 は見えない方の説明。
>>218 は見える方(というか無名サブルーチン内からの変数の見え方)の説明。
02222162006/06/11(日) 19:06:08
すみません、ちょっと確認させて下さい

test01.pl--------
#!/usr/bin/env perl
require 'test02.pl';

my $value = 10;
test(sub { print $value; });
---------------

test02.pl--------
sub test {
  $sub = shift;
  &$sub;
}
---------------

実行結果:10

test02.plを以下のようにしてもうまくいかない
test02.pl---------
sub test {
  print $value;
}

こういう理解であっているでしょうか?
0223デフォルトの名無しさん2006/06/11(日) 20:04:01
>>222
> 本来なら直接アクセスできない変数にアクセスでき
に対する理解としては多分良いと思う。が、
クロージャとコールバックに対する理解の話だとするならば、ずれてるな…
以下、高階関数に関する説明をしようかと思ったけれど上手く纏まらないので略。

ちょっと寄り道してschemeのlambdaと高階関数とか調べてみると確実な理解がしやすいかもね。
schemeのlambdaはクロージャそのものだから。
0224デフォルトの名無しさん2006/06/11(日) 21:10:48
そもそも「クロージャ」(closure)bチて名前はレキャVカル変数を「封ツじ込める」事bゥら来てるって�フい人が言ってbス
0225デフォルャgの名無しさん2006/06/11(日) 21:37:46
>>216

すんません、俺もよくわかりません。

my $total_size = 0;
find(sub { $total_size += -s if -f }, "."};
print $total_size, "\n";


>変数$total_sizeが無名
>サブルーチンのスコープの外部で宣言されているにも
>かかわらず、この無名サブルーチンは変数にアクセス
>しています。

>本来なら直接アクセスできない変数
>にアクセスでき

外部で宣言されたmy変数にアクセスできるのは当たり前だと思うのです。
スコープの内側ならサクセスできないけど、なんで自分より外のmyにアクセスできると変なのかわからないです。

find関数の内部実行って意味の話なのかな?
これはリファレンスが送られるから、find関数で値は参照されますが…。
クロージャのスコープは定義した場所で決定して、実行場所とは関係ないから参照できて当たり前と思うのです。

ごめん、なんか問題の意味すらよくわからなくなった orz
0226デフォルトの名無しさん2006/06/11(日) 21:49:17
my $closure;
{
  my $hoge = "abc";
  $closure = sub { print "$hoge\n"; };

  $closure->();      # abc
  print "$hoge\n";  # abc
}
$closure->();        # abc
print "$hoge\n";    # エラーになる


$hoge はレキシカル変数なのでブロックの中でのみ有効。
しかし、クロージャの中にレキシカル変数を閉じ込めると、ブロックの外でも参照できる。
こんな感じでわかるかな?
0227デフォルトの名無しさん2006/06/11(日) 21:50:30
>>225
>なんで自分より外のmyにアクセスできると変なのかわからないです。
多分、>>216 で挙げられている本の例があまり良くないのだと思う。

外部のmyにアクセスできると変、というか不思議でしょ?とその本が言いたいのは
>>222 で挙げられている例の test() のように、
作成された無名サブルーチンを別のスコープに持って行っても
その無名サブルーチンを定義した時に見えていた my変数がそのまま見える
という所だと思う。
02282252006/06/11(日) 22:09:14
あ、意味がわかりますた。

02292162006/06/12(月) 00:46:10
みなさんいろいろと勉強になります

>>226の内容は理解できました

>>225
意味わかったのかぁよかったね・・・
俺はまだ理解しきれません
あと少しで理解できそうです
すみません、最後に聞かせて下さい

a.pl--------------------
use File::Find;
my $total_size = 0;
find(sub { $total_size += -s if -f }, "."};
print $total_size, "\n";
-----------------------
これについてなんですが、
上記のfindに渡されるクロージャの無名サブルーチンは
>>225が言うように、
a.plのスコープで実行されるんじゃなくて、
File/Find.pm内のfind関数のスコープで実行されるんですよね?
File/Find.pmのfind関数のスコープからは、a.plのスコープにある
$total_sizeは見えないはずなのに、クロージャを使うことで見える
ようになる、ということで間違っていないですか?
0230デフォルトの名無しさん2006/06/12(月) 01:17:27
>>229
> a.plのスコープで実行されるんじゃなくて、
> File/Find.pm内のfind関数のスコープで実行される
うわぁ、違う。一番肝心なところが違う。
というか最後から7~4行目と2~1行目で言っていることが矛盾していないか。
その本の言いたいことはその後ろに、
「ように思うかもしれないが、クロージャは作られた場所の(静的)スコープが記録されており、
find関数がどうなっているかは関係なく、クロージャの作られたスコープで動作する。」
と続く。

ちなみに、呼び出し元が動的スコープだった場合(つまりこのときはクロージャではない)は
呼び出された関数から見えることもある。File::Findの例ではパッケージが違うので見えないけれど。
{
  local $var = 10;
  function(sub { print "anonymous: $var\n" });
}
sub function {
  print "function: $var\n"; # localだと$varが見える
  $var = 5; # 勿論書き換わる
  shift->();
}
0231デフォルトの名無しさん2006/06/12(月) 01:42:21
.plファイルにpatch.exe diff.exeのパッチをあてたいのですがやり方がわかりません
何かツール必要なのでしょうか?
色々調べたんですけどわかりませんでした
0232デフォルトの名無しさん2006/06/12(月) 01:46:11
んー、このレベルで話す時ドコで実行されるの話は変になってくる。
その本も変だし。
>クロージャの作られたスコープで動作する
この表現も微妙。

あえてドコで実行されるかを言えば、クロージャのリファレンスのアクセス先。
>>229は、クロージャの理解としては正解。
どこで実行されるとかよりも、クロージャがある限りmy変数が消えないで残ってるんだよ、ってところが重要なのであり、べつに「ドコで」とかはもうどうでもいい気が。答えようがないし。

---------------------

{
 my $hoge;
}

#通常、この場所では$hogeは内部的にも消滅してる
#Perlは参照が不可能になった変数は破棄する。

---------------------

{
 my $hoge;
  our $closure = sub {$hoge = $hoge + 1}
}
#この場合、クローバル変数closureを通して$hogeが参照されるので、$hogeは消滅しないし、
#$closureをデリファレンスすると$hogeにアクセスされる。
#レキシカルスコープ(my)は静的なスコープで、コンパイル時に見たまんまのスコープが適用される。
#で、$hogeはこの時みたまんまのレキシカルスコープを持ってるんであって、ドコで実行とかは関係ない。
#だからxxのスコープで実行されるとかの表現も少し変。
#xxはyyのスコープにある、とかyyのスコープを持っているとか表現しる。
#ドコのスコープで実行されるとかは、動的なダイナミックスコープの話で、クロージャとダイナミックスコープは関係ない。
---------------------
02332302006/06/12(月) 02:39:00
>>232
ごめん、確かに表現が悪かった。その上に意図を取り違えてたらしい。
否定した部分も、クロージャ内からfindのローカル変数にアクセスできてしまうかとか
そういう意味で捉えてしまっていたけれど、普通に動的スコープの話だと考えれば合ってたな。
と言うことで230撤回させてくださいorz 申し訳ない
02342162006/06/12(月) 09:12:02
>>230
「間違いを正してくれてありがとうございます
やっと、なんとか一応理解できました」
と思ったら
>>233で撤回されてしまいました
もうわけわかめ

>>232すみません。もっかい確認させて下さい

1.pl-------------------
#!/usr/local/bin/env perl
require '2.pl';
my $value = 10;
function( sub { print $value; } );
----------------------
2.pl-------------------
sub function {
shift->();
}
1;
----------------------
$perl a.pl
10

上記において、1.plでmy宣言された$valueは
シンボルテーブルにも登録されずレキシカルスコープを持っているので、
その有効範囲は本来1.pl内にとどまるはず。
たとえ1.pl内でrequire '2.pl';としても2.plの内容は$valueのスコープ、
つまり1.plのファイルスコープには組み込まれない。
だから2.pl内のfunction内で$valueの値をprintしても何も表示されない、
ように思えるが、クロージャの作用でちゃんと$valueは10と表示される。
この理解で大丈夫ですか?
0235デフォルトの名無しさんNGNG
至極当然の動作な気が
0236デフォルトの名無しさん2006/06/12(月) 11:30:33
perlのsortって内部ではどういうソートやっているんですか?
バブルソート?クイックソート?
0237デフォルトの名無しさん2006/06/12(月) 12:12:28
perldoc sort に書いてあるです。
基本はマージソート。設定によりクィックソートも可。
0238デフォルトの名無しさん2006/06/12(月) 13:51:04
質問です
Fcntl.pmの:flockの
LOCK_SH LOCK_EX LOCK_NB LOCK_UN
の値は全てのプラットフォームで共通でしょうか
0239デフォルトの名無しさん2006/06/12(月) 13:57:20
>>237
らくだ本のsortの項目には書いてないことが
5.8.7のperldoc sortにはたくさん書いてあるね
昔はデフォルトでクイックソートだったが、
5.8からはマージソートになったんだね
勉強んなったありがとー
0240デフォルトの名無しさん2006/06/12(月) 14:51:30
>>238
違う値になってるのは見たことはないが、同じである保証はないと
思って書いとけ。
0241デフォルトの名無しさん2006/06/12(月) 16:21:57
ぎゃー
表示があかしくなってしましました。

以前は、「total 単位:万」とtを下に横書きで表示されていたのですが、
下記のようになりました。

万
:
位
単
l
a
t
o
t

GDのバージョンを2にしたのが原因かと思われますが、
さくっと解決する方法ありますでしょうか?
フォントとか変えるだけでうまくいかないものでしょうか?
0242デフォルトの名無しさん2006/06/12(月) 16:37:46
>>241
perlの問題違うやん
0243デフォルトの名無しさん2006/06/12(月) 17:14:39
>>241
知らないけど、文字の描画方向が下から上の縦書きになってんじゃないの?

そんな自然言語見たことないが。(世界は広いからどこかにあるかも知れないな)
0244デフォルトの名無しさん2006/06/12(月) 20:21:20
mod_perl時の場合END{}はプロセスが終了した時のみに実行されますが
mod_perl時にPerl/CGIのEND{}と同様の事をしたい場合どうするのが一番良いのでしょうか。
0245デフォルトの名無しさん2006/06/12(月) 20:41:21
P***Gua****というものを導入しろと言われたのですが*に入る文字って何か分かりますか?
0246デフォルトの名無しさん2006/06/12(月) 20:52:11
>>244
WebProg板にmod_perlのスレがあるのでこちらへどうぞ
http://pc8.2ch.net/test/read.cgi/php/1149505269/
0247デフォルトの名無しさん2006/06/12(月) 21:04:50
$a=6;
for($i=0;$i<100;$i++){
$a=$a-0.1;
print("$a\n");
}

のようにすれば6から0.1ずつ引いていってくれるはずだと思ったのですが、
ある数値を境に、0.99999998などというような数値になってしまいます。
何か間違えている部分はありますでしょうか。
0248デフォルトの名無しさんNGNG
>>245
PeerGuardian?
一文字多いか
0249デフォルトの名無しさん2006/06/12(月) 21:23:59
>>247
浮動小数点の処理には誤差が伴う。
「正確な値」になることを期待することがそもそも間違い。
http://www.kt.rim.or.jp/~kbk/perl-5.8/perlfaq4.html#why_am_i_getting_long_decimals__eg__19_9499999999999__instead_of_the_numbers_i_should_be_getting__eg__19_95_
0250デフォルトの名無しさんNGNG
まぁ
use bignum;
でもしてろってこた
0251デフォルトの名無しさん2006/06/12(月) 21:31:39
なるほど。
因縁みたいなもんなんですね。
0252デフォルトの名無しさん2006/06/12(月) 21:40:27
>>245
PerlGuandam
■ このスレッドは過去ログ倉庫に格納されています