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

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

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
"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/04/26現在の最新版: 5.8.8
● 2006/04/26現在の開発版: 5.9.3

リンク集は>>2-3
過去スレは>>4
0153デフォルトの名無しさん2006/05/06(土) 19:59:38
>>152
N分後ならtime()+60*n
N時間後ならtime()+60*60*n
N日後ならtime()+60*60*24*n

うるう秒みたいな特殊なケースを除けばこれは絶対に正しい?
0154デフォルトの名無しさん2006/05/06(土) 20:25:23
>>153
正しくないケースを伸べよ。
0155デフォルトの名無しさん2006/05/06(土) 20:30:25
>>153
「60*n」等の式が正しいとすれば(正しいだろう)
現在のエポック秒に求める秒数を足してるのだから明らかに正しい。
なんせ年月日時分の概念が無いんだから。
0156デフォルトの名無しさん2006/05/06(土) 20:45:06
掛け算で閏秒はどうやって解決しているのか、ぜひ聞かせていただきたい物だ
0157デフォルトの名無しさん2006/05/06(土) 20:59:20
>>156
ちゃんと>>155読んだ?
0158デフォルトの名無しさん2006/05/06(土) 21:38:31
>>157
阿呆は放置。
0159デフォルトの名無しさん2006/05/06(土) 21:45:48
>>154
ビーーン
0160デフォルトの名無しさん2006/05/06(土) 21:53:29
>>156
本来の要求仕様がわからんから正確にはなんとも言えんが、
「n秒後」という要求では、逆にうるう秒は考えちゃいけないだろ。

「x月y日まであと何秒?」という場合なら考えなきゃいけないが。
0161デフォルトの名無しさん2006/05/06(土) 22:05:07
どっちにしても、うるう病は地球の自転の観測結果から調整するもので、うるう年みたいな
規則性がないからどうしようもないけどね。
0162デフォルトの名無しさん2006/05/06(土) 22:10:13
次のPerlの仕様がどうたらこうたらってきいたのですが
仕様がそんなにかわるんですかね?

簡単に仕様変更を書いたサイトとかってないですかね?
0163デフォルトの名無しさん2006/05/06(土) 22:12:43
つか、エポック秒なんだから、そもそも考える必要性がないだろ?
0164デフォルトの名無しさん2006/05/06(土) 22:14:09
ていうか何がしたいねん
0165デフォルトの名無しさん2006/05/06(土) 22:20:46
キチガイ君は放って置けよwww
0166デフォルトの名無しさん2006/05/06(土) 22:41:47
エポック社といえば
0167デフォルトの名無しさん2006/05/06(土) 22:45:26
ビッグエッグ野球盤
0168デフォルトの名無しさん2006/05/06(土) 22:47:15
バーコードバトラー
0169デフォルトの名無しさん2006/05/06(土) 23:44:57
>>162
http://dev.perl.org/perl6/
Pugs含め現状どうなってるかは知らない
0170デフォルトの名無しさん2006/05/07(日) 00:13:35
おまいら責め杉だ
0171デフォルトの名無しさん2006/05/07(日) 00:17:03
use CGI::Util qw( expire_calc );

my $time = expire_calc('+7y'); # 3年後のエポック秒
日付に関しちゃ年によってずれるだろう。


0172デフォルトの名無しさん2006/05/07(日) 01:03:57
>>171
なにがずれるん?
0173デフォルトの名無しさん2006/05/07(日) 01:07:29
>>171
>use CGI::Util qw( expire_calc );

いや、それ、31日ある月の計算すらしてないよ。
my(%mult) = ('s'=>1,
'm'=>60,
'h'=>60*60,
'd'=>60*60*24,
'M'=>60*60*24*30,
'y'=>60*60*24*365);
を掛けてるだけだから。
0174デフォルトの名無しさん2006/05/07(日) 01:09:54
.exeっていうファイルもつくれるのか?この言語は
01751732006/05/07(日) 01:11:30
>>172
閏年の計算してないんで、おそらく、2/29の有無によって、1年後の日付が1日ずれるって言いたいと思われ。
0176デフォルトの名無しさん2006/05/07(日) 01:18:10
今からn秒後が閏年であろうがなかろうがn秒後であることには変わりがない。
0177デフォルトの名無しさん2006/05/07(日) 01:22:16
>>174
反則技を使えばできないこともない。でも基本的にそういう言語ではない。
0178デフォルトの名無しさん2006/05/07(日) 01:25:21
>>175
要するに任意の日付までの秒数を求めようとしている人がいるわけね…
0179デフォルトの名無しさん2006/05/07(日) 01:32:38
日付は歴史と密接な関係があるからなぁ。
0180デフォルトの名無しさん2006/05/07(日) 01:36:32
こうまとめたらいいかな?

N秒後は + N (間違いなし)
N分後は + N*60 (閏秒でズレる)
N時後は + N*60*60 (閏秒でズレる)
N日後は + N*60*60*24 (閏秒でズレる)
N月後は + N*60*60*24*30 (31日の月、閏年、閏秒でズレる)
N年後は + N*60*60*24*30*365 (31日の月、閏年、閏秒でズレる)
0181デフォルトの名無しさん2006/05/07(日) 01:37:57
スルー
0182デフォルトの名無しさん2006/05/07(日) 01:56:54
>>177
ええええええ
俺がやりたいのは、市販のプログラム に乗っかって パケット解析しつつ
そのパケットをアルゴリズムで分析して(かなり原始的なアイデアはいくつかあるから実験したい)
 命令出す ってのなんだけど この言語でいけるかな?
トップ企業では普通にやってるらしいが
その関係者がにちゃんでぼろっと言ってたのだと、そいつはむかしperlつかって組んだらしい

ネトゲでマクロやってて正規表現の基本とかはわかってる
ただ、ネックだったのはパケットとアルゴリズムでした。

らくだ本と、アルゴリズムの基礎を学校の図書館で借りてきた。パケットはあとまわし。
とりあえず自動ログインツールをつくることを目標にしてるけど、

exeで動かさないなら、いちいちperl login.plとか打って起動させなきゃならんの?
login.pl の末端に autorun.plを起動させる文かいたりして、
条件 しだいで buy.plとかを動かす、とかそんなふうに組んでくの?

リアルタイムでどんな処理してるかビジュアルで把握したかったら、
別のプログラムが必要なんかな?VBちょっとやったことあるけど、あれは窓をすぐにつくれるじゃん?
0183デフォルトの名無しさん2006/05/07(日) 02:08:54
華麗にスルー
0184デフォルトの名無しさん2006/05/07(日) 02:28:09
>>182
>exeで動かさないなら、いちいちperl login.plとか打って起動させなきゃならんの?
>login.pl の末端に autorun.plを起動させる文かいたりして、
>条件 しだいで buy.plとかを動かす、とかそんなふうに組んでくの?

そうだよ
0185デフォルトの名無しさん2006/05/07(日) 02:31:02
閏秒や閏年に対応したけりゃ DateTime 使うか zic が leapsecond に対応した環境で
localtime() 使えばいいだけじゃないの?

>>180
「閏秒でずれる」という表現がおかしいでそ。
例えば「3分後」は 3 * 60 = 180秒後であって、間に閏秒を挟んでいても
それは変わらん。
0186デフォルトの名無しさん2006/05/07(日) 04:59:06
x/x/x x:x:x から n 秒後を y/y/y y:y:y
として、間に閏秒があった場合、
(y/y/y y:y:y)−(x/x/x x:x:x) ≠ n になっちゃうか。
0187デフォルトの名無しさん2006/05/07(日) 08:23:49
たとえば「1分後」といったときに、60秒後のことを言っているのか、
次の分の同じ秒のことを言っているのかをはっきりさせないまま
話しているのでなんだかよくわからなくなってるような。

前者の意味なら常に秒数だけ気にしていればいいが後者だと閏秒が
でてくる。

DateTimeだと1分後と60秒後は区別していて、1分後は閏秒こみだから
こんな例がマニュアルにある。

# 1971-12-31 23:59:30 - our starting datetime

$dt->clone->add( minutes => 1 );
# 1972-01-01 00:00:30 - one minute later

$dt->clone->add( seconds => 60 );
# 1972-01-01 00:00:29 - 60 seconds later

$dt->clone->add( seconds => 61 );
# 1972-01-01 00:00:30 - 61 seconds later
0188デフォルトの名無しさん2006/05/07(日) 11:13:22
過去の閏秒は分かっているからいいけど、未来だとどうしてもズレちゃうよね。
01891532006/05/07(日) 12:08:48
とりあえずうるう秒以外に例外はないってことが分かっただけで十分です
ありがとうございました
0190デフォルトの名無しさん2006/05/07(日) 12:38:12
しかしまじめに閏秒の設定して使ってる人っているのかね?
今まで見たことないんだが。
0191デフォルトの名無しさん2006/05/07(日) 14:09:29
>>190
天文関係とか、年単位で正確な秒数が必要な科学技術計算では必須だよ。
0192デフォルトの名無しさん2006/05/07(日) 19:01:29
で、実際にそんな人見たことあるわけ?
0193デフォルトの名無しさん2006/05/07(日) 20:48:34
改行区切りの文字列("abc\ndef\nghi)を1行ずつ処理する方法ありますか?
地道にindexとsubstrやれば出来そうですが。
0194デフォルトの名無しさん2006/05/07(日) 20:55:08
@lines = split(/\n/, $string);

楽チンチン
01951932006/05/07(日) 21:06:03
>>194
ありがとう。
splitは改行使えないと思いこんでた・・・orz
0196デフォルトの名無しさん2006/05/07(日) 21:34:12
よく天文学的な数字って言うけどPerlで桁足りるんだろうか。
use bignum 入れて速度保とうとすると面倒だしさ。

>>190
閏病を調整する人が使えば当然必要だーね。
0197デフォルトの名無しさん2006/05/07(日) 23:13:33
>>196
crackmeのkeygen作るのに、Math::BigInt使って、Perlで16進数16桁の平方を求めるとかはやったことあるけどね。
0198デフォルトの名無しさん2006/05/08(月) 07:21:37
s///ee
という表現があるようなんですが
これは何でしょうか?
eは置き換え後文字列部分を式評価するという意味
ですが、なんで二つ並んでいるの?
0199デフォルトの名無しさん2006/05/08(月) 08:04:03
(それを書いた人にとっては)見た目が良いから。
0200デフォルトの名無しさん2006/05/08(月) 08:24:43
>>198
式評価した結果を更に式評価したいから。
02011982006/05/08(月) 09:14:16
>>200
ありがとう。でもよくわからない
0202デフォルトの名無しさん2006/05/08(月) 10:19:37
>>201
$_ = "aXb";
s/X/"1+1"/ => a"1+1"b
s/X/"1+1"/e => a1+1b
s/X/"1+1"/ee => a2b

まともなコーディングで二重評価する必要性のある例がなかなか思い浮かばないけど…何か良い例あるかね
とりあえずFAQ
ttp://www.kt.rim.or.jp/~kbk/perl-5.8/perlfaq4.html#how_can_i_expand_variables_in_text_strings
0203デフォルトの名無しさん2006/05/08(月) 11:00:38
>>146 ヽ(`Д´)ノ

>>147
ありがとうございます。結局こちらでは、

use encoding "cp932";
use open ":encoding(cp932)";
use open ":std";

と、最後に use open ":std"; を追加することで対応できました。
確かにencoding、馬鹿ではよく理解できない。。。

>>148
確かにcp932の問題ではなかったですね。失礼しました。
use openを付けたのは、実際の処理の際には、
テキストファイルを読み込む場合が多いので、
その状況も検証したかった、というのが理由です。

>>149
jperl時代のお手軽さに慣れてしまってたので。。。
02042012006/05/08(月) 16:11:27
>>202
ありがとう。
とりあえずわかったけど
おっしゃる通り使い道が浮かばない
0205デフォルトの名無しさん2006/05/08(月) 16:36:55
>>202
> まともなコーディングで二重評価する必要性のある例がなかなか思い浮かばないけど…何か良い例あるかね

う〜む、具体的に思い出せないが、かつて「あれってこのためにあったのか!!」と
驚愕した記憶がある。
0206デフォルトの名無しさん2006/05/08(月) 17:39:21
中に書く式で自分でevalすりゃいい話のような気がするのだが、
それでは本質的にできないようなことなのだろうか?
0207デフォルトの名無しさん2006/05/08(月) 17:57:02
思い出せないんじゃしょうがない
0208デフォルトの名無しさん2006/05/08(月) 19:31:36
>>202
> まともなコーディングで二重評価する必要性のある例がなかなか思い浮かばないけど…何か良い例あるかね

どっかのカスCGIで、HTMLテンプレート展開ルーチンに
そんなのが使われてたのを見た記憶が。
0209デフォルトの名無しさん2006/05/08(月) 21:15:57
s/<\?php(.*?)\?>/$1/ee;
0210ヽ(´ー`)ノ ◆.ogCuANUcE 2006/05/09(火) 02:05:12
まぁ普通にURLデコードとか。

s/%([[:xdigit:]]{2})/pack('H2', $1)/ge;
0211デフォルトの名無しさん2006/05/09(火) 02:46:04
>>210
一重じゃん。
0212デフォルトの名無しさん2006/05/09(火) 03:05:35
ワロス
0213デフォルトの名無しさん2006/05/09(火) 07:53:18
>ヽ(´ー`)ノ ◆.ogCuANUcE
>ヽ(´ー`)ノ ◆.ogCuANUcE
>ヽ(´ー`)ノ ◆.ogCuANUcE
0214デフォルトの名無しさん2006/05/09(火) 12:37:33
ee = Enterprise Edition

企業気分になれるんだよ。
0215デフォルトの名無しさん2006/05/09(火) 13:32:27
s/u//gee;
0216デフォルトの名無しさん2006/05/09(火) 14:49:57
ちょっとは、お役に立てるかな?
http://www.yukinko-net.jp/computer/download/downloadlist.htm
0217デフォルトの名無しさん2006/05/09(火) 19:47:30
Perlってなんでこんなに楽しいの?
0218デフォルトの名無しさん2006/05/09(火) 19:57:06
>>217
ラリってる奴が作ってるから。
0219デフォルトの名無しさん2006/05/09(火) 20:09:59
>>217
脳内麻薬物質が出てくるからです。
0220デフォルトの名無しさん2006/05/09(火) 20:11:15
ぶっちゃけ>>214に納得
0221デフォルトの名無しさん2006/05/09(火) 20:17:28
>>214は深いね。
0222デフォルトの名無しさん2006/05/09(火) 20:59:17
220,221=214
0223デフォルトの名無しさんNGNG
俺も思った
0224ヽ(´ー`)ノ ◆.ogCuANUcE 2006/05/10(水) 00:44:44
>>211-213
すまん、全然読んでなかった…orz
0225デフォルトの名無しさん2006/05/10(水) 00:52:21
perlfaq7 に一つ、二重評価の例があるけど、あまり良い例じゃないな…。
0226デフォルトの名無しさん2006/05/10(水) 05:43:21
>>202
/e の多重評価って確か、意図した仕様じゃなくて、開発側も当初は気づかなかったけど結果として可能になっちゃってた、というモノだったと思ふ。

「面白いからそのまま feature にしようぜ」、というノリが Perl 流か。w
0227デフォルトの名無しさん2006/05/10(水) 07:29:35
winでホームディレクトリへ移動するにはどうすれば?
use Cwd;
chdir('~');
print Cwd::getcwd();

しても変化なし

0228デフォルトの名無しさん2006/05/10(水) 07:38:56
とあるディレクトリで
@list = glob('*');
print @list;
とすると
a.plb.plc.pl
となる

また、
$list = (glob('*'))[0];
print $list;
とすると
a.pl

これを
$list = glob('*');
print $list;
とすると
a.pl
となる
どうしてc.plにならないの?

たとえば
$str = qw(a b c);
print $str;
とするとcになるのに
0229デフォルトの名無しさん2006/05/10(水) 07:48:24
>>227
chdir($ENV{'USERPROFILE'});
0230デフォルトの名無しさん2006/05/10(水) 08:53:51
>>228
readlineと同じでスカラコンテキストではイテレータになるから
ドキュメントではファイル名グロブ<>の方かな
0231デフォルトの名無しさん2006/05/10(水) 09:29:04
>>229
さんくす!
でもこのUSERPROFILEっていう環境変数は誰が
セットしているの?
マイコンピュータ→環境変数とたどって一覧みたけど
USERPROFILEなんてなかったよ
win2000proですけど。
0232デフォルトの名無しさん2006/05/10(水) 09:37:17
EffectivePerlに載ってたんだけど

print "hello, " && print "goodbye.";
が
goodbye1
になるのはなぜ?

print "hello, " and print "goodbye.";
ならきちんと
hello, goodbye
となる

andと&&の優先順位の違いが原因だろうとは
思うんだけど具体的に何が起こっているのかわからない
0233デフォルトの名無しさん2006/05/10(水) 09:47:06
>>227
chdir の引数を省略するとホームディレクトリに移動する。参考まで。
HOME が未設定の環境でどうなるかは知らん。
0234デフォルトの名無しさん2006/05/10(水) 10:21:06
>>231
explorer.exe
0235デフォルトの名無しさん2006/05/10(水) 10:23:32
>>232
優先順位の問題。

print は引数にリストを取るので、連続したリストに見える後続の全てを引数として飲み込む。ひとつの文中で、print のようなリスト演算子モドキの後に何か別の処理を書く時にはこの動作に注意しなくてはいけない。
引数をそれぞれ () で括るのが最も万能の対策。() を使わずに何か後続させようとする場合は、より優先順位の低い not、and、or、xor のいずれか、あるいは制御構造修飾子を使うべし。

最初の && を用いた文は次のようにパースされる。

print( "hello, " && print( "goodbye.") );

perl はまず && の左辺 "hello, " を評価する。リテラル "hello, " は Perl の有効な真値であるため、次に右辺の print() が評価される。
print は出力に成功すると真値 '1' を返すのでこれも真と評価される。よって && の両辺が真となり、最後に評価された値である '1' が、最初の print の引数として渡され、それが出力される。

てな感じ。
0236デフォルトの名無しさん2006/05/10(水) 10:24:53
>>232

>print "hello, " && print "goodbye.";
print ("hello, " && (print "goodbye."));

>print "hello, " and print "goodbye.";
(print "hello, ") && (print "goodbye.");
02372142006/05/10(水) 12:44:50
>>222-223
えっ、いや、それぶっちゃけちがう人だよ。
俺的にはぶっちゃけ>>215がSUGEEEEEEE!!!

s/a//ge;
0238デフォルトの名無しさん2006/05/10(水) 15:03:45
>>233
C:\>perl -MCwd -echdir(); -eprint(Cwd::getcwd());
C:/Documents and Settings/Administrator

おーう、知らなかったぜ
0239デフォルトの名無しさん2006/05/10(水) 16:03:16
>>233
なんだ単にchdirの引数省略すりゃよかったのか
どうもありがとうもー
0240デフォルトの名無しさん2006/05/10(水) 16:13:07
eachで頭が壊れそうです

my %hash = (a=>1, b=>2, c=>3);

foreach (each %hash)
{

print $_ , "\n";

}

この結果が
c
3
になるんだけど意味わからんのです
perldoc -f each
で読んでみると
eachはスカラーコンテキストで呼ばれると次のキーのみを返すとあります
foreach ()の()の中はスカラーコンテキストですよね?
なのにどうしてprint $_ , "\n";
の結果が
c
3
なんかになるのだろう

それと、どうしてハッシュ全体が$_にセットされないの?
foreach (each %hash)としたら
まず一回目のループでeach %hashされて一つ目がとりだされて
つぎのループでまたeach %hashされて二つ目がとりだされて
っていうふうにならないのはなぜ?
ループ一回しか回らんのですが
どういうからくりか教えてくださ・・・い
0241デフォルトの名無しさんNGNG
そのまんまじゃねえか
foreachに使う配列がeachで取り出した(c,3)になってる
ここでも参考にしてコード書き直せ

http://perl.misty.ne.jp/function01/each.html
0242デフォルトの名無しさん2006/05/10(水) 16:19:33
>>235
超わかりやすかった
さんくふぉーゆー
02432402006/05/10(水) 16:20:51
>>241
あ、なるほど
うわぁああん
0244デフォルトの名無しさん2006/05/10(水) 16:57:59
perldoc -f each でサンプルプログラムまで出てくるというのに…
0245デフォルトの名無しさん2006/05/10(水) 17:19:50
そもそもforeach (...)のカッコ内がスカラーコンテキストだと思っている時点で間違い
0246デフォルトの名無しさん2006/05/10(水) 18:01:55
以前こんな風に書いてあるのを見たことがある。

$i = 0;
for $n (1..100) {
 $a[$i] = $n;
 $i++;
}

Perl の心を伝えるのは難しいものよのう。
0247デフォルトの名無しさん2006/05/10(水) 19:13:29
>>245
pritn for 1
これが構文的にはOKだしね
0248デフォルトの名無しさんNGNG
プリトン
0249デフォルトの名無しさん2006/05/10(水) 20:25:03
>>247
Unquoted string "pritn" may clash with future reserved word at - line 1.
Useless use of a constant in void context at - line 1.
- syntax OK


ほんとだ。syntax は OK らしい。
0250デフォルトの名無しさん2006/05/10(水) 20:49:17
>>245
そっかforeach(...)のカッコ内はリストコンテキストだったんだね
0251デフォルトの名無しさん2006/05/10(水) 23:16:03
コンテキスト以前に、foreachは()内を一回しか評価しないということ。
配列を返す関数get_array()でforeachは(get_array() ){...}
とか書いてもget_array()一回分の配列しか取らない。

eachで取り出した配列であるキーと値が一回分出てきている。
全ての値が見たいなら
print $_ , "\n" foreach (%hash);
とかでオケ
0252デフォルトの名無しさん2006/05/10(水) 23:20:26
てか
print join( "\n", %hash, "\n");

デバッグ目的なら
use Data::Dumper;
print Dumper( \%hash );
■ このスレッドは過去ログ倉庫に格納されています