トップページ⇒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
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 );
0253デフォルトの名無しさん2006/05/11(木) 00:31:15
>>252Data::Dumper超便利だねありがとー

>>251そっか単にハッシュをforeachでまわせばよかったのか
ありがとー

0254デフォルトの名無しさん2006/05/11(木) 01:21:05
「each は while のオプション」くらいの認識でだいたいヨシ。
0255デフォルトの名無しさん2006/05/11(木) 02:39:39
Perlのスレッドっていくらなんでも重過ぎない?
スレッドごとにインタプリタの環境を複製するから仕方ないのかな?
perl -e 'use threads;push(@TL,threads->new(sub{}))for(0..99);sleep 10;$_->join for(@TL)'
0256デフォルトの名無しさん2006/05/11(木) 05:51:01
>>255
うん、激重な上にメモリもかなり消費。
0257デフォルトの名無しさん2006/05/11(木) 09:51:08
文字コードをEUCかSJISかを変数で切り替えるようにしたいんだけどうまく表示できません
どうすればうまくいくんでしょうか?

$mozi_code="euc-jp";
#$mozi_code="sjis";


$str="文字コードテスト";

print "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$mozi_code\">";
print "<HTML>";
&jcode'convert (*str,$mozi_code);

print "文字列=$str";
print "</HTML>";
0258デフォルトの名無しさん2006/05/11(木) 10:22:04
HTMLの勉強しる

print "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$mozi_code\">";
print "<HTML>";
ってなによ。
0259デフォルトの名無しさん2006/05/11(木) 10:30:22
>>258
途中省略しただけ
これでもちゃんと表示できないんだけど

$mozi_code="euc-jp";
#$mozi_code="sjis";
$str="文字コードテスト";

print "<HTML>\n";
print "<HEAD>\n";
print "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=$mozi_code\">";
print "<TITLE>$title</TITLE>\n";
print "<BODY>";

&jcode'convert (*str,$mozi_code);

print "文字列=$str";

print "</BODY></HTML>";
0260デフォルトの名無しさん2006/05/11(木) 11:09:25
以下のサブルーチンが何やってるか意味不明です

sub is_tainted {
return ! eval {
join('', @_), kill 0;
1;
};
}

if(is_tainted($value))

などとして$valueが汚染されているかをチェックするらしい


join('', @_), kill 0;
が特に理解できない

kill 0でプロセスの状態がチェックできるのはわかったけど
いったいどのプロセスをチェックしてるんだ?
本当ならkill 0, xxxというふうにプロセスID指定しなきゃならんのでは?
0261デフォルトの名無しさん2006/05/11(木) 11:22:22
>>258
print "文字列=$str";

とりあえずこの「文字列=」の部分も変換すれ
0262デフォルトの名無しさん2006/05/11(木) 11:37:33
>>260
kill 0は汚染チェックされる物なら何でもよくて、特にkill 0でなければならないというわけではない。
たぶん実行しても他に影響なさそうなものということで選んだと思われる。

そしてなぜだかわからないがperlsec(1)の例にあるように、

$arg, `true`; # Insecure (although it isn't really)

汚染されたデータと危険な操作を,で並べたときも汚染チェックでNGになるので、is_taintedの
パラメタが汚染されていたときは実行時エラーの発生によりevalの戻り値がundefになる。
0263デフォルトの名無しさん2006/05/11(木) 12:35:56
&jcode'convert (*str,euc);だとうまくいくのに
&jcode'convert (*str,euc-jp);だとエラーがでるのはどうしてですか?
0264デフォルトの名無しさん2006/05/11(木) 13:14:15
なぜperl4
0265デフォルトの名無しさん2006/05/11(木) 13:25:49
>>263
jcode.plのconvertは文字コードの指定はeuc,jis,sjisのどれかしか受付けない。
euc-jpは結果的に空文字列になるがそのどれでもない。
0266デフォルトの名無しさんNGNG
素直にJcode.pm使った方が…
0267デフォルトの名無しさん2006/05/11(木) 13:39:23
>>265
ちょっ、euc-jp の結果は 0
0268デフォルトの名無しさん2006/05/11(木) 13:54:41
>>267
ありゃ、確認するために

print euc-jp;

としたら空文字列だったんだが、よくかんがえるとこれは
eucというファイルハンドルに-jpをprintしていたのか...
すまん。
02692602006/05/11(木) 14:26:07
>>262
ごめん。理解できなかった

0270デフォルトの名無しさんNGNG
jcode.plの57-58行目読めよ
0271デフォルトの名無しさん2006/05/11(木) 14:59:39
EUCコードに改行って含まれるんでしょうか?
0272デフォルトの名無しさん2006/05/11(木) 15:07:16
&jcode'convertでEUCに変換するときソースコードの表示する文字列部分を一つずつ

&jcode'convert (*str1,euc);
&jcode'convert (*str2,euc);
&jcode'convert (*str3,euc);
というようにしなければならないのですか?

ページ全部一括でEUCに変換できないんですか?
0273デフォルトの名無しさんNGNG
含まれるんじゃないかな?
http://euc.jp/i18n/charcode.ja.html
0274デフォルトの名無しさん2006/05/11(木) 15:27:13
なんか凄い奴がいるな……。
正しい行き先教えてやれよ。
0275デフォルトの名無しさん2006/05/11(木) 15:34:14
>>273
つまりフォームから送信されたデータをファイルに書き込んで保存する場合は
EUCに変換して保存するのはやめたほうがいいということですね?
0276デフォルトの名無しさんNGNG
( ゚д゚)ポカーン
0277デフォルトの名無しさん2006/05/11(木) 16:17:37
>>275
>>1読んで。
0278デフォルトの名無しさん2006/05/11(木) 16:18:32
>>269
kill がシグナル送信に成功したプロセス数を返すことを思い出したら、
kill 0; の戻り値を確認するといいよ。

>>262 は、この(一見)無意味なkill 0; の役割だね。
0279デフォルトの名無しさん2006/05/11(木) 17:15:29
>>272
&jcode'convert (*all_str,euc);

>>275
どこをどう読むと(ry
02802692006/05/11(木) 17:28:26
>>278
ありがとう。
でもごめん
もっとわからなくなった
0281デフォルトの名無しさん2006/05/11(木) 17:36:25
>>279
データの保存方法ですが

1:フォームから送信されたデータをEUCに変換して保存してEUCとして読み込んで表示する
2:フォームから送信されたデータをSJISで保存して読み込むときEUCに変換するして表示する

のどっちがいいか知りたかっただけです
それでどっちがいいんでしょうか?
0282デフォルトの名無しさん2006/05/11(木) 17:42:11
>>281
自分のすきな方でいいんじゃないかな。

保存より表示の回数が多いなら、保存時に変換しておくと変換回数を減らせる。
まぁ、効果は小さいものだろうけど。
個人的には、表示を EUC で行うなら EUC で保存しておくのが好みだけど。
0283デフォルトの名無しさん2006/05/11(木) 17:53:54
板違いはしょうがないとしても指摘されたら改めろ。
それを助長するように回答付ける方もカスだが。
0284デフォルトの名無しさん2006/05/11(木) 18:03:22
>>283
指摘されたのが自分だと気づいてないんじゃないだろうか。
0285デフォルトの名無しさん2006/05/11(木) 19:27:25
>>283
まぁもちつけ。
それから、もっとまともな指摘をしろよ。
0286デフォルトの名無しさん2006/05/11(木) 19:33:56
perlで以下のようなpasswdファイル文字列の"Hoge"の部分だけ小文字にしたいと考えています。
hoge:kwaKjt6IJ/rBs:1100:100:Hoge,,,:/home/hoge:/usr/bin/csh

区切りが:と,の2つあるので下のようにしました。

m/(.*):(.*):(.*):(.*):(.*):(.*):(.*)/;
@MA = split(',',$5);
$MA[0] = lc($MA[0]);
$MA2 = join(',',@MA);
print "$1:$2:$3:$4:$MA2:$6:$7\n";

ところがこれをおこなうと、小文字に変わりますが",,,"が消えてしまいます。
hoge:kwaKjt6IJ/rBs:1100:100:hoge:/home/hoge:/usr/bin/csh

,,,のところはnullだけでなく文字が入る場合もあります。
どうすれば
hoge:kwaKjt6IJ/rBs:1100:100:hoge,,,:/home/hoge:/usr/bin/csh
のようなかたちになりますか?
0287デフォルトの名無しさん2006/05/11(木) 19:40:11
>>286
splitのマニュアルを、良く読め。
3つ目のパラメータだ。
0288デフォルトの名無しさんNGNG
@MA = split(',',$5,-1);

とか
0289デフォルトの名無しさん2006/05/11(木) 19:55:43
(.*): より ([^:]*): の方が良くないか?
0290デフォルトの名無しさん2006/05/11(木) 20:01:09
>>286
s/(.*?:.*?:.*?:.*?:)(.*?):/$1.lc($2)/e;
0291デフォルトの名無しさん2006/05/11(木) 20:06:45
みなさんありがとうございます。
@MA = split(',',$5,-1); でうまくいきました。
0292デフォルトの名無しさん2006/05/11(木) 20:09:12
s/^((?:[^:]*:){4})([^,]*)/$1.lc($2)/e;
0293デフォルトの名無しさん2006/05/11(木) 20:57:22
>>285
まともな指摘がなされてると思うが

0294デフォルトの名無しさん2006/05/11(木) 21:09:19
>>259
取り繕ってもダメ。大文字でタグを書く人間がHTMLを勉強しているはずがない。
0295デフォルトの名無しさん2006/05/11(木) 21:50:26
>>294
論理的じゃない理論だが、納得。
0296デフォルトの名無しさん2006/05/11(木) 23:33:03
>>294
昔は、本文と区別しやすくするためにHTMLは大文字で書くのが良いとされていたのになぁ
0297デフォルトの名無しさん2006/05/12(金) 00:28:53
終戦直後はそうだったよなぁ
0298デフォルトの名無しさん2006/05/12(金) 01:05:18
>>296
>>259がその手の人とは思えませんが?
0299デフォルトの名無しさん2006/05/12(金) 01:24:25
一行ごとに print文使うのは突っ込むところじゃないのか?
0300デフォルトの名無しさん2006/05/12(金) 03:34:05
みんなマメだね。w
0301デフォルトの名無しさん2006/05/12(金) 03:39:50
Perlを愛するみんな!! ありあまっているそのパワーを、フリーソフトウェアを作ることに向けようよ!!

そうすれば、世の中少しは良くなるよ!!
0302デフォルトの名無しさん2006/05/12(金) 04:13:18
>>301
Perlを愛してるなんて気持ちはないと断言できる!
0303デフォルトの名無しさん2006/05/13(土) 03:17:41
WindowsXP proでwin32::DDEをインストールし
ppm install http://www.bribes.org/perl/ppm/Win32-DDE.ppd
Excelの一番左上のセル(C1R1)の内容を延々と表示するプログラムを書きました。

#!/Perl/bin/perl
$client = new Win32::DDE::Client ('excel', "Sheet1");
print sprintf('%06d ', ++$i), $client->Request ('R1C1') while 1;

32768回目(2^16 / 2)のリクエストから挙動がおかしくなり
49152回目(2^16 / 4 * 3)からは4回に1回しか値が取得できなくなり
65536回目で
「Undefined subroutine &main:: called at C:/Perl/site/lib/Win32/DDE/Callback.pm line 46.」
とエラーを吐きます。このエラーをググると
http://www.google.com/search?num=50&hl=ja&ie=UTF-8&oe=UTF-8&q=%22Callback.pm+line+46%22&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=
2件ヒットしますが解決に至りませんでした。
何かいいアイディアはありませんでしょうか。
0304デフォルトの名無しさん2006/05/13(土) 08:30:11
>>303
以前 Win32::DDE 使ったことあるけど、おれもエラーが出た。
そのときソース(Win32::DDE のperl部分)もみたけどよく分からなかった。

Win::32::DDE::Callback には

TO DO
Test, debug, document; this hasn't been touched since the original version, and
doesn't seem to be used by Win32::DDE::Client, so no rush :)

と書かれてるけど、Win32::DDE::Client によって使われてるし。

2^15 や 2^16 回でエラーが発生してるということは、モジュール自体あたりのバグかも
しれないね。
Win32::DDE ではなく、Win32::API を使うという方法はどうかな。
0305デフォルトの名無しさん2006/05/13(土) 10:30:58
PDFを読めるようなモジュールってないでしょうか。
今はpdftotextを呼び出して使っているんですが、
その部分を自分で作ってしまえればすっきりするかなぁと思っています。
0306デフォルトの名無しさん2006/05/13(土) 10:39:48
http://search.cpan.org/search?query=PDF&mode=all
いろいろあるようだけど、どれがおすすめとかは知らない
03073052006/05/13(土) 11:07:44
>>306
ありがとうございます。

実はすでにモジュールのサーチはしてたんですが、
作るためのモジュールと読み出すためのモジュールの区別も付かなかったんです。
英語力なさ過ぎです。
せめてサンプルプログラムでもあれば想像で何とかできるんですが…。
0308デフォルトの名無しさん2006/05/13(土) 11:26:39
特定のコマンドラインオプションが指定されていた場合は
指定されたファイルに出力
されていなかった場合は標準出力
というように処理を分けたいのですが、何かいい方法はないでしょうか
今はいちいち if で処理を分けているのですが
けっこう量が多いので面倒なのです

$ some_script.pl -o foo.txt
foo.txt に結果を書き込む
$ some_script.pl
結果を標準出力する
0309デフォルトの名無しさん2006/05/13(土) 11:33:11
>>304
ありがとうございます。
XSの方のソースをちょっと眺めてみます。
9年前に作成されたモジュールでVer0.02だから多くを求めるのは無理なのかもしれませんねーー)
0310デフォルトの名無しさん2006/05/13(土) 12:02:11
>>308
リダイレクトじゃだめなのかい
some_script.pl > foo.txt
0311デフォルトの名無しさん2006/05/13(土) 12:15:12
>>308
select
open STDOUT,...
open $fh,'>&STDOUT' や $fh = *STDOUT
0312デフォルトの名無しさん2006/05/13(土) 12:48:33
>>308
つーか その出力用のメソッド作れば?
0313デフォルトの名無しさん2006/05/13(土) 12:53:56
それはなんか美しくないなぁ
0314デフォルトの名無しさん2006/05/13(土) 13:30:14
open FILE, ...
select FILE;

de ii jan.
むしろ >>310 でいいじゃん。
03153082006/05/13(土) 14:21:17
>>310
すみません、書き忘れていました
途中経過を標準出力したかったので
リダイレクトは使いたくなかったのです
>>311 でうまいこと実現できたのでこれを使わせていただきます
どうもありがとうございます
0316デフォルトの名無しさん2006/05/13(土) 15:42:56
途中経過はSTDERRに出せばええやん…
0317デフォルトの名無しさん2006/05/13(土) 16:08:21
それはなんか美しくないなぁ
0318デフォルトの名無しさん2006/05/13(土) 19:55:37
use strict; しちゃうと、どうやってもtrue/false は使えなくなるの?
0319デフォルトの名無しさん2006/05/13(土) 21:03:32
Perlにはtrue/falseのリテラルないよ
0320デフォルトの名無しさん2006/05/13(土) 21:10:10
0と1でいいじゃん
0321デフォルトの名無しさん2006/05/13(土) 22:07:14
use constant false => 0;
use constant false => 1;

じゃ駄目なん?
0322デフォルトの名無しさん2006/05/13(土) 22:07:50
うわ、コピペミス
use constant true => 1;
ね。


0323デフォルトの名無しさん2006/05/13(土) 23:05:15
win2kのコマンドプロンプトでactiveperlを使っています
テキストの表示で、一部だけ色を付けるにはどうすればいいですか?
config.sys書き換えて、とかは無しの方向で
0324デフォルトの名無しさん2006/05/13(土) 23:13:39
>>323
Term::ANSIColor
Win32::Console::ANSI
0325デフォルトの名無しさん2006/05/13(土) 23:49:56
>>323
自前でエスケープコード送ったりする方法も使えるかも。一応。
モジュール使う方が断然いいけど。
0326デフォルトの名無しさん2006/05/14(日) 00:20:42
エスケープコードは、cmd.exeが無視するので使えません
ansi.sysを組み込んでcommand.comから起動すると使えるようですが、
それはあまりに一般的でないので避けたい
0327デフォルトの名無しさん2006/05/14(日) 03:49:46
無視するので使えません
って自分で言ってんじゃん。
0328デフォルトの名無しさん2006/05/14(日) 05:26:52
cmd.exe では使えないけど、command.com では使えるってことじゃまいか。
ま、モジュール使うということでよさそうだけど。
0329デフォルトの名無しさん2006/05/14(日) 11:22:33
いやいや、cmd.exeで動いてる他のexeファイルで
カラー表示してるのは普通にあるから、ESC[31m とかに頼らなければ
方法はある筈なんだけど、perlでどうやるんだろうと

Term::ANSIColor は試してみたけど、エスケープコードを代わりに
出してくれるだけだったので効かなかった
0330デフォルトの名無しさん2006/05/14(日) 11:33:07
Win32::Console::ANSI がそれを解決するのか

Windows NT/2000/XP does not support ANSI escape sequences in
Win32 Console applications.
This module emulate an ANSI console for the script which uses it.

でもインストールの敷居が高い
0331デフォルトの名無しさん2006/05/14(日) 11:54:32
nmakeはなんとか落としてきたけど、
Cコンパイラは何を使えばいいんだろう
■ このスレッドは過去ログ倉庫に格納されています