Perlコーディング初心者質問スレ Part 52
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2006/09/15(金) 14:01:51ID:gobry0n2【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >>2-10
前スレ http://pc8.2ch.net/test/read.cgi/php/1153987463/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0690nobodyさん
2006/11/04(土) 13:39:03ID:???理由は、今まで Perl + SSI でやっていたので、2重に実行環境が呼び出されて負荷が高いと思われるので、(SSIの負荷はPerlに比べれば少ないですが) Perlのみでやってみたいからです。
----- test.cgi -----
#!/usr/bin/perl
print 'Content-Type: text/html' . "\n\n";
require 'test.html';
exit;
----- test.html -----
print << '_HTML_';
<html>
<head>
<title>テスト</title>
</head>
<body>
<h1>テスト</h1>
<p>ちゃんと表示されるかな。</p>
</body>
</html>
_HTML_
1;
ヒアドキュメント部分を print << "_HTML_"; では無く、print << "_HTML_"; にしたら、
文字コードが Shift_JIS であっても、駄目文字が使えてこのままでも結構いいのですが、
test.html に HTML以外のPerl命令 (上1行と下2行) をいれないといけないのが、
美しくないかなーと思いまして。
綺麗なコードでこのようなことをやる方法をご存知の方がいたら教えてください。
0691nobodyさん
2006/11/04(土) 13:52:42ID:???0692nobodyさん
2006/11/04(土) 13:58:02ID:???意図が今一つかめんのだが以下の方法じゃあかんのか?
----- test.cgi -----
#!/usr/bin/perl
print 'Content-Type: text/html' . "\n\n";
print <DATA> ;
__DATA__
<html>
<head>
<title>テスト</title>
</head>
<body>
<h1>テスト</h1>
<p>ちゃんと表示されるかな。</p>
</body>
</html>
0693690
2006/11/04(土) 14:05:18ID:???ありがとうございます。
そのモジュールにも興味が出てきたので、機会があったら使ってみます。
>>692
多数のCGI (とHTMLファイルに含まれるSSI) から include したいので、別ファイルにしたいと思ってたんです。
教えていただいた通りのコードで、やりたいことができそうです。
ありがとうございました。
----- test.cgi -----
#!/usr/bin/perl
print 'Content-Type: text/html' . "\n\n";
open DATA "test.html";
print <DATA>;
exit;
----- test.html -----
<html>
<head>
<title>テスト</title>
</head>
<body>
<h1>テスト</h1>
<p>ちゃんと表示されるかな。</p>
</body>
</html>
0694nobodyさん
2006/11/04(土) 14:09:19ID:???http://www.ipa.go.jp/security/awareness/vendor/programming/a04_01_main.html
負荷が同じ程度なら sysopen でもいいですが、OSの関数ダイレクトってことなので
sysopenのが重いんじゃないかな、と思ったんだけどちゃうかな
0695690
2006/11/04(土) 14:44:33ID:???test.cgi のソースに問題があったようです。
修正版は次の通りです。
----- test.cgi -----
#!/usr/bin/perl
print 'Content-Type: text/html' . "\n\n";
open(DATA, "< test.html");
print <DATA>;
close(DATA);
exit;
0696nobodyさん
2006/11/04(土) 17:03:05ID:???結局どちらもOSのopenに行くところは一緒で余計な機能がない分
sysopenの方が軽いともいえるが普通は気にするほどの差はない。
しかしこれ書いた人3引数open知らないのだろうか?
0697nobodyさん
2006/11/04(土) 21:40:25ID:foW9asSJmixiのようにhttp://〜.plの様にしたいのです。
そのままperlを表示しようとするとダウンロードになったしまいます。
よろしくお願いいたします。
0698nobodyさん
2006/11/04(土) 21:54:00ID:???それはPerlではなくサーバー側の設定によります。
例えば Apache の場合 .htaccess で設定できる可能性があります。
詳しい方法は、検索するなり、お使いのサーバーソフトウェアのスレにいくなり、
借りているウェブスペースの管理者に問い合わせるなりしましょう。
0699nobodyさん
2006/11/04(土) 22:59:12ID:foW9asSJ有難うございます。
結構調べたんですが、全く出てきませんでした。
サーバーはApacheなんで調べてみます。
0700nobodyさん
2006/11/04(土) 23:31:40ID:???0701nobodyさん
2006/11/06(月) 14:38:08ID:???(因果関係はまだはっきりしていませんが、時期が一致したし、CGIの負荷が増えたと思われるので、その可能性が高いと考えてます。)
Perl のバージョンは v5.8.6 で OS は Fedora Core 4 です。
CGI に加えたコードは、モジュール "Encode" の読み込み (use Encode;) と、
POST時に送信されたデータに対して "$_ = encode('sjis', decode('sjis', $_));" を加えたぐらいです。
後者のロジックではせいぜい10程度のデータに対して encode と decode をしているだけだし POST数はそんな多くないんで、
"use Encode;" が負荷の原因だと思われます。
DoCoMoのケータイからのアクセスで最後の方に Shift_JIS として不正なデータが含まれてしまったりすることもあるんで、(DoCoMoのブラウザのバグか電波が不安定なのかは知りません。)
Shift_JISとして不正なデータが含まれた場合にも「エラー処理」でなく「不正な文字列の削除(エスケープ)」としての対処を行いたいです。
"use Encode;" を使わずに、低負荷でこの処理を行う方法はないでしょうか?
>>116 で大丈夫ですかね。
0703nobodyさん
2006/11/06(月) 16:04:47ID:???たとえ10万PV/dayであろうとも、POST数がそんなに多くないのならCGIの負荷が
多少かわったところで影響は大きくなさそうなものだ。それともPOST以外でも
CGIがkickされまくっていて不要なuse Encodeをしているという話だろうか??
性能問題は本当に性能のボトルネックになってるところを突き止めて対策しないと
骨折り損になるよ。
0704nobodyさん
2006/11/06(月) 16:18:18ID:???場合によっては \t \r \n も不正な文字として扱う必要があるかもしれないけど。
use Encodeって結構コストが高いからなぁ。
まぁ、因果関係がまだはっきりしてないんだったら、もう少し調べてみたほうがよいかもね。
0705nobodyさん
2006/11/06(月) 16:30:09ID:???CPU食うようだ。これはちょうどuse CGIと同じぐらい。無視できる量ではないがとてつもなく大きい
わけでもないな。もとがぎりぎりならきびしいかもしれないが。
0706nobodyさん
2006/11/06(月) 16:30:59ID:???0707nobodyさん
2006/11/06(月) 16:51:09ID:???Encode、Jcode、CGI、GD、IO::Handle、Time::HiRes…
とどんどんuseしていくと一気に遅くなるのが分かる
0708nobodyさん
2006/11/06(月) 17:10:00ID:???モジュール削って不便なプログラミングで苦労するよりはmod_perlなり
fastcgiなり使ったほうが幸せになれる気がする。
0709701
2006/11/06(月) 17:45:18ID:???このスレにあったようなので読みました。
>>703
> それともPOST以外でもCGIがkickされまくっていて不要なuse Encodeをしているという話だろうか??
#!/usr/bin/perl の次の行で use Encode; をしています。(10万PV/日の CGIで)
マルチバイトXSSの対策前の部分で use Encode; しても大丈夫なんでしょうか? 試してみます。
use は一番上でやるもんだと思ってました。
ただ、ループ内でやると、use Encode が何度も実行されることになるので、変数でフラグたてて1回のみやるようにしてみますね。
それでうまく動かなかったら正規表現でやってみます。
> 性能問題は本当に性能のボトルネックになってるところを突き止めて対策しないと
> 骨折り損になるよ。
ですね。
さっき当該部分(マルチバイトXSS対策)のコードを消してしばらく動かしているんですが、負荷は少し減っているような気がします
グラフのデータが少なくてまだ確実とはいえないので、1日ぐらいこのまま動かしてMRTGのグラフで比較してみますね。
>>705
もとがぎりぎりではないんですが、MRTGのグラフ (Load Average 5min 15min) でいままでピークでも60%ぐらいが上限だったのに、
ピークで100%ぐらいにいくようになったんです。面積をよくみると、2倍まではいってなくて、もとの1.5倍ぐらいかも。
>>707
なるほど
>>708
自分が作ったのではないコードが含まれていてぐちゃぐちゃなので mod_perl はきびしそうです
グローバル変数多用、同じようなコードを関数を使わずに何度もかいていたり同じエスケープ処理を何箇所かでやってたりで
とにかくぐちゃぐちゃです;;
0710nobodyさん
2006/11/06(月) 17:58:01ID:???CGIはたくさん起動されているが本当にEncodeモジュールを必要とする場合が少ないのならば、
確かにもったいないね。可能なら機能ごとに別のプログラムに分離したほうがいいんじゃないか
とも思うが、いまさらそれも無理なら小手先の対策として、Encodeモジュールを必要とするとき
のみuseするのがいいだろう。
ただし普通にuse書いてしまうとどこに書いてあっても最初にプログラム読み込むときにuseされて
しまうので、必要なときだけ eval 'use Encode;';するのがいいと思われる。ブロックではなく
文字列のevalを使うのが肝。
0711nobodyさん
2006/11/06(月) 20:29:39ID:???これはPHPの中の人のブログだが、一度読んでおくことを勧める
ttp://blog.ohgaki.net/index.php/yohgaki/2006/06/12/
0712701
2006/11/06(月) 20:56:58ID:???レスありがとうございます。
教えていただいたサイトを読ませていただきました。
不正なデータを 「サニタイズ」 した結果、他の有害なデータになってしまうということは良くありますね。
上位のファイルの読み出しを禁止するために 「../」 を削除するコードにしたら、「..././」 → 「../」 となってしまうというのが有名な例です。
こういった問題が発生しないよう良く考えてみることにします。
不正な文字コードが含まれていたらエラーを返す、というのが理想かもしれませんが、それをやるとアクセシビリティ上の問題が発生してしまいます。
例えば、そのサイトで推奨している mb_check_encoding 関数の場合でもそうですが、「@」とか「T」が含まれていただけでも、エラーになりますし、
ケータイからですと顔文字が1つ含まれただけでエラーになります。(Shift_JISの場合に確認、他の文字コードでも発生すると思われます。)
データベースは使っていないし、データベースについての知識はないのでそれについては分かりませんが、HTMLとして出力したりファイルに出力したりする
普通のCGIで入力段階 (他のチェック前) で不正な文字列を 「削除」 した場合には、発生するおそれのある脆弱性がおもいあたりません。
勿論、他のチェックのあとでやればそれによって、他のチェックが無効になり危険ですが…。
0713nobodyさん
2006/11/06(月) 21:21:16ID:???正常な文字以外は通すな。
削除しただけで正常な文字になると思うな。
って、言いたかったんでないかの。
文字コードのチェック→(不正文字は排除済みとみなした上で)サニタイズ。
この流れで十分でしょう。
0714701
2006/11/06(月) 21:31:38ID:???解説ありがとうございます
UTF-8 の構造は複雑でまだ理解できていませんが、Shift_JIS や EUC-JP の場合には
バイナリレベルで 「2バイトで1文字となる範囲のバイナリデータが1文字目にある(単独で存在する)」 場合にそれを削除すれば、
マルチバイトでのXSS問題に限れば完璧に回避できますね。(2バイト連結文字の1バイト目の文字がなければ問題は発生するわけがないので。)
また、1バイト=8bit を区切りにして操作を行えば、削除によってまた他の不正なマルチバイト文字列ができあがることはないはずです。
0715nobodyさん
2006/11/06(月) 22:54:18ID:???0716nobodyさん
2006/11/07(火) 00:30:07ID:???XSS脆弱性はそんなに単純じゃない。たとえば、0x5Cの問題。
0717nobodyさん
2006/11/07(火) 20:13:30ID:???> たとえば、0x5Cの問題。
それについて興味があるので詳細を教えていただけないでしょうか?
もし、無理ならば Shift_JIS の問題か EUC-JP の問題かだけでも教えていただけたらさいわいです。
0718nobodyさん
2006/11/07(火) 20:50:37ID:???0719nobodyさん
2006/11/07(火) 22:21:56ID:???0720nobodyさん
2006/11/07(火) 23:25:16ID:???0721701
2006/11/08(水) 00:25:38ID:???EUC-JPには3バイト文字もあったんですか・・・。
EUC-JPに関する知識が不十分で申し訳ありませんでした。
お詫び申し上げます。
0722nobodyさん
2006/11/08(水) 00:31:45ID:???0723nobodyさん
2006/11/08(水) 00:34:30ID:???> XSS脆弱性はそんなに単純じゃない。たとえば、0x5Cの問題。
0x5C 問題 (表示が文字化けするなど) は、XSS (マルチバイト文字列でのXSSも含む) には全く関係ないと思うんですけど・・・。
そもそもこの問題は、エスケープシーケンス (\) が解釈される場所のみで問題が発生するわけで、エスケープシーケンスを解釈しないWebブラウザでは問題無いですよね。
そして、エスケープシーケンスを解釈するブラウザなんて見たことないし、あったとしたら問題です。
<strong>この商品は \1000だよ</strong> って書いただけで不具合起こすんです?
データベースなどのエスケープシーケンスを解釈する場所に、>>714 の処理をしたデータを突っ込んだ場合には問題は発生するかもしれないけど、Perl単独ではありえない。
(ファイルに出力したPerl文を実行するなどの特殊な場合を除く)
$hoge = "テスト\\"; // $hoge に "test\" が入る。
print "$hoge"; // $hoge を出力する。
たとえば、こう書いた場合に、$hoge が test\ に書き換わって、
print "test\";
となって、" が排除されエラーになることはないからね。
「2バイトで1文字となる範囲のバイナリデータが1文字目にある(単独で存在する)」 場合にそれを削除 でマルチバイトXSS問題は完璧に解決すると思う。(Shift_JIS限定)
不正な1バイトデータが残ったところで、それがマルチバイトとして扱われることはないから、問題ない。
0724723
2006/11/08(水) 00:36:38ID:???0725nobodyさん
2006/11/08(水) 01:29:59ID:???以下のHTMLを受け取った時に解析して 送信 を送信するといった処理を望んでいますが、
今のソースでは 取り消し が送信されます。
送信、取り消しの違いはokの有無ですが、これを区別する方法を教えてください。
<FORM ACTION="hoge.cgi" method="POST">
<INPUT TYPE=HIDDEN NAME=huga VALUE="huge">
<INPUT TYPE=SUBMIT NAME=ok VALUE="送信">
<INPUT TYPE=SUBMIT VALUE="取り消し">
</FORM>
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
$string = "上のHTML";
$url = 'http://hoge/hoge.cgi';
$string =~ /NAME=huga\sVALUE="(.*?)"/;
%formdata = ('huga' => $1);
$ua = LWP::UserAgent->new;
$req = POST($url, [%formdata]);
res = $ua->request($req);
0726nobodyさん
2006/11/08(水) 03:11:43ID:Z752EjWSすまん。質問の意味わかんね
0727nobodyさん
2006/11/08(水) 04:32:08ID:CtUHOCOJ%formdataはhugeが入ってるんじゃね?
0728725
2006/11/08(水) 04:32:26ID:x1PlsJ4Csubmitボタンが複数ある時の選択方法を教えてください。
0730nobodyさん
2006/11/08(水) 04:38:11ID:???prog板から来たよんw
submitも普通のエレメントと一緒だよ。
nameがあってvalueがある。
submitの場合は押された部品のname&valueが渡される。
押されていないsubmitは渡されない。
この説明で分かるかしら。
0731725
2006/11/08(水) 04:43:05ID:x1PlsJ4Cできましたw
ありがとうございました。
0732nobodyさん
2006/11/08(水) 04:46:44ID:???例として、http://some.kind.of.uploader/upload.phpのページにある
<form enctype="multipart/form-data" action="upload.php" method="post">
<input type="file" name="userfile" size=50>
<input type="submit" value="SUBMIT">
</form>
というフォームに対して、ローカルの/path/to/file/にあるtest.jpgをアップロードす
るとします。
my $url = 'http://some.kind.of.uploader/upload.php';
my $ua = LWP::UserAgent->new();
my $response = $ua->post($url, ['userfile' => '/path/to/file/test.jpg']);
としてみましたがうまくアップロードできません。
できない理由として考えられることは何がありますでしょうか?
また、同様の趣旨でもっといい方法がありましたら御教授お願いします。
0733nobodyさん
2006/11/08(水) 05:34:44ID:???つ php.ini
0735nobodyさん
2006/11/08(水) 08:08:20ID:???サーバーからのメッセージとしては、手動で行なった場合にファイル名を入力しなかっ
たのと同じ「アップロードするファイルを入力してください」というものです。
>>734
そんな感じですね。
と、言うわけで自己解決しました。requestを使用します。
my $file = '/path/to/file/test.png';
my $response = $ua->request(POST $url,
Content_Type => 'form-data',
Content => ['userfile' => [$file]]
);
0736nobodyさん
2006/11/08(水) 22:57:15ID:???何か問題ありますか?
@deny = ("0.0.0.0","1.1.1.1");
$addr = $ENV{'REMOTE_ADDR'};
foreach $ip (@deny) {
if ($addr eq $ip) {print "エラー";
last;}
}
0737nobodyさん
2006/11/08(水) 23:08:19ID:???my @deny = (
"0.0.0.0",
"1.1.1.1",
);
foreach my $ip (@deny) {
if ($addr eq $ip) {
print "error";
last;
}
}
0738nobodyさん
2006/11/08(水) 23:17:40ID:???Perl5以降は local でなくて my を使うのが推奨されているようだ
0739736
2006/11/08(水) 23:41:20ID:???|⌒σ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
|冫、) < >>737-738 ありがとう。 |
|` / \_________/
| |
|/| |
| ∪
|
| / ̄ ̄ ̄ ̄\
|< さらばじゃ |
| \____/
|)彡 サッ
|
|
|
|
0740nobodyさん
2006/11/08(水) 23:51:59ID:???my %deny = (
"0.0.0.0" => 1,
"1.1.1.1" => 1,
);
if ($deny{ $ENV{'REMOTE_ADDR'} }) {
print "error";
last;
}
0741nobodyさん
2006/11/08(水) 23:57:39ID:???0742nobodyさん
2006/11/09(木) 00:02:09ID:???0743nobodyさん
2006/11/09(木) 09:09:18ID:???0744nobodyさん
2006/11/09(木) 10:28:57ID:???0745nobodyさん
2006/11/09(木) 15:33:45ID:???error() if index($deny, $ENV{REMOTE_ADDR}) >= 0;
0746nobodyさん
2006/11/09(木) 18:25:08ID:???|⌒σ
|冫、)
|` /
| |
|/| |
| ∪
|
0747nobodyさん
2006/11/09(木) 19:33:08ID:???WindowsでGDを使いたいのですが、同時にインストール必要なモジュールって他にありますか?
ppmでGDをインストールして、サンプルを参考に
画像を読み込んで表示するだけのスクリプトを書いてみたのですが
GD::Imageで指定したサイズの黒い四角は表示されるものの、画像そのものは表示されません。
UNIXでは他にも複数のライブラリのインスコが必要という記事を見つけたので調べているんですが
Windows(ActivePerl)ではどうなんでしょうか。
0748nobodyさん
2006/11/09(木) 19:36:56ID:???0749nobodyさん
2006/11/09(木) 19:37:47ID:???MRTGでグラフを書いてるのはEXEバイナリだったorz
0750nobodyさん
2006/11/09(木) 20:23:24ID:???0751701
2006/11/09(木) 20:52:58ID:???use Encode; と $_ = encode('sjis', decode('sjis', $_)); を外しただけで、
サーバ全体の負荷(5min, 15min uptime) が MRTG のグラフで目視して明らかに分かる程度に減ったので、
CGI負荷の増大の原因はそれにあったことがほぼ決定しました。
>>116 の方法を採用してみます。
0752747
2006/11/09(木) 20:56:36ID:???どもです。余裕見て参照してみます。
>>750
ホントですかー。動いてるんですね。
でもそれがわかっただけでも大助かりです。
おかげで絞り込めてきましたので、なお見直してみます。
ありがとうございました!
0753701
2006/11/09(木) 21:29:43ID:???>>704 に
> 「不正な文字コードが見つかれば、以降の文字はすべて無効」でOKなら116で問題ないかと。
とありましたが、
116の方法では、不正な文字列(マルチバイト文字列の1バイト目が単独で存在) が 文の中央付近に入っていた場合でも、
その不正な文字列の除去のみが行われて、それ以降の文字列は正常に受け取れました。
(※不正な文字列はきちんと除去されていました。)
ちなみに、$_ = encode('sjis', decode('sjis', $_)); 方式と違って、丸付き文字 @AB なども正常に受け取れるようです。
(よいか悪いかは別にして…)
負荷の問題はもうちょっと運用してみて結果が出たら報告させていただきます。
回答してくださったみなさまありがとうございました
0754nobodyさん
2006/11/09(木) 22:17:24ID:3KxQ4Diolocal宣言して別パッケージから参照している変数がtypoと言われて
しまいます。
現在、
> local $main::upload_dir = './attach_file/';
と書いてあるものを
> local $main::upload_dir;
> $main::upload_dir = './attach_file/';
とすると警告が出なくなります。typoだけ警告をきるようなことは可能でしょうか。
よろしくお願いします!
0756nobodyさん
2006/11/10(金) 05:24:46ID:???プログラムの概要は、
フォルダ内の「会員ID.txt」(中身はメールアドレス)をopendirで会員IDの配列を作る。
forの中で、open(会員ID)→メールアドレス格納→sendmailで送信。
会員IDの配列分だけ繰り返し。
といった感じです。
メールの内容にも会員IDを埋め込みたいのでこのような方法にしています。
ブラウザからアクセスして実行してみましたが、現在会員数は20人足らずにもかかわらず
少し重そうだったので他にいい方法はないかと質問させていただきました。
0757nobodyさん
2006/11/10(金) 08:34:04ID:???送信先メールサーバの名前解決をしてユーザがそんざいするかとか
今送れるかどうか問い合わせたり
相手が忙しいと待たされたり
とにかくメール送信が負荷よりも時間のほうがかかる
もし自サーバになんらかの負荷がかかってればsendmailは自動的に待ち状態になる設定になってるはず
0761nobodyさん
2006/11/11(土) 17:04:01ID:jBOZHEcG0762nobodyさん
2006/11/11(土) 18:16:33ID:???0763nobodyさん
2006/11/11(土) 18:37:34ID:???0764nobodyさん
2006/11/11(土) 18:45:16ID:???0765nobodyさん
2006/11/11(土) 19:51:38ID:???それはそれですげぇな
0767766
2006/11/11(土) 20:43:59ID:???0768nobodyさん
2006/11/11(土) 20:44:20ID:???探せばわからなくもない。ただしopenしたあとに削除されてたらアウト。
0769nobodyさん
2006/11/11(土) 21:39:58ID:srC1L817aaa => @aaa,
bbb => @bbb,
ccc => @ccc
);
のように、fooオブジェクトのhogeメソッドに配列を渡す時、
sub hoge {
my $self = shift;
my %args = @_;
$self->{aaa} = ?; // @aaaを入れたい
$self->{bbb} = ?; // @bbbを入れたい
$self->{ccc} = ?; // @cccを入れたい
・
・
・
}
とした場合、%argsからどのようにして@aaa、@bbb、@cccを受け取るのでしょうか。
0770nobodyさん
2006/11/11(土) 21:51:54ID:???$foo->hoge(
{
aaa => ¥@aaa,
bbb => ¥@bbb,
ccc => ¥@ccc
}
);
sub hoge {
my $self = shift;
my $args = shift;
$self->{aaa} = $args->{aaa};
・
・
}
まあ実際の処理ではこんな事しないと思うよ。
してたら設計ミスを疑った方が。
0771nobodyさん
2006/11/11(土) 21:59:26ID:???my $self = shift;
my %args = @_;
$self->{aaa} = $args{aaa};
0772nobodyさん
2006/11/11(土) 22:01:07ID:srC1L817ありがとうございます。
では、OOPにおいてメソッドの呼び出し時に配列を渡す場合の受け渡しはどうなるのでしょうか?m(_ _)m
0773nobodyさん
2006/11/11(土) 22:04:15ID:srC1L817ありがとうございます。
その方法は試しましたが、受け取り側($self->{aaa})が配列の要素数を受け取ってしまいました。。。
0774nobodyさん
2006/11/11(土) 22:15:26ID:dAHcCPkr>>772
>>770のとおりで良いと思う。
hashの要素としてlistを直接持てないから、listのリファレンスにするわけ。
0775nobodyさん
2006/11/11(土) 22:25:12ID:srC1L817$self = {
aaa => undef
};
として受け取った場合、$self->{aaa}を配列として扱うことは可能なのですか?
0776nobodyさん
2006/11/11(土) 22:26:23ID:???$self->{aaa} = @{$args{aaa}};
と配列変数のリファレンスを受け取るって書いたつもりでした。
そうすれば、引数のリストを>>770のように匿名ハッシュで囲わなくてもいいんじゃないか、と。
0777nobodyさん
2006/11/11(土) 22:48:53ID:???配列として、は無理。配列のリファレンスとして、扱う。
ちなみに>>770氏は引数全体をhashのリファレンスにし、且つ個々のlist(@aaa とかの部分)も
listのリファレンスにしてるけど、後者は必須だが、前者はただのhashにもできるね。
$foo->hoge(
aaa => ¥@aaa,
bbb => ¥@bbb,
ccc => ¥@ccc
);
sub hoge {
my $self = shift;
my %args = @_;
foreach my $key (keys %args) {
$self->{$key} = $args{$key};
}
}
# @{$self->{$key}} で配列全体を、$#{$self->{$key}} で要素数-1を、$self->{$key}->[0] で個々の値を参照できる
>>776
I see.
0778nobodyさん
2006/11/11(土) 22:55:37ID:???@_ にはサブルーチンの引数がフラットなリストとして展開・格納されます。
また "=>" は本質的に "," のエイリアスに過ぎません。
すなわち @aaa = ( 'xxx', 'yyy', 'zzz' ) である時、hoge( aaa => @aaa ) は hoge( 'aaa', 'xxx', yy'y', 'zzz' ) と等価です。
さらには %args = ( aaa => @aaa ) とやってしまうと、
$args{aaa} == 'xxx'
$args{yyy} == 'zzz'
という内容のハッシュが出来上がります。これは恐らくあなたが望むものではないでしょう。
サブルーチン引数やハッシュ代入における配列 (より正確には全ての非スカラー) の独立性を保つには、偶然にも同じ解決策が使えます。
「リファレンス」がそれで、>>770 で実装の一例が述べられています。
perlref, perllol, perlsub などのマニュアルが役に立つでしょう。
# 他の言語から Perl に移行する場合は混乱するよな、実際。
0779nobodyさん
2006/11/11(土) 23:07:00ID:5mpuYPBZ理解するまでしばらくかかりそうなので、理解してまた返信させていただきますm(_ _)m
0780nobodyさん
2006/11/11(土) 23:28:01ID:t9lEuzhq(なんか良く分からなくなってきましたが・・・)
質問に答えていただいた方、ありがとうございました。
ところで、こういう細かいことが書かれているオンラインのマニュアルなどはあるのでしょうか?
0781nobodyさん
2006/11/11(土) 23:44:57ID:???>>779
特に perlref。ぐぐればいいよ。
listもhashも、複数の値でできてる。複数の値なんで、それを一つの値であるかのように、
$a{'aaa'} = @aaa;
とすることはできない。
しかし、リファレンスっていうのはそれ自体は一つ。なので、
$a{'aaa'} = ¥@aaa;
は可能なんですよ。
%aa = ('aa' => 'AA', 'aaa' => 'AAA');
%bb = ('bb' => 'BB', 'bbb' => 'BBB', 'bbbb' => 'BBBB');
hoge(%aaa, %bbb);
はhogeに10個の引数を渡していることになるけど、
hoge(¥%aaa, ¥%bbb);
は2個の引数を渡してるんですよ。
0782nobodyさん
2006/11/11(土) 23:48:10ID:???%aa = ('aa' => 'AA', 'aaa' => 'AAA');
%bb = ('bb' => 'BB', 'bbb' => 'BBB', 'bbbb' => 'BBBB');
hoge(%aa, %bb);
はhogeに10個の引数を渡していることになるけど、
hoge(¥%aa, ¥%bb);
は2個の引数を渡してるんですよ。
0783nobodyさん
2006/11/12(日) 01:13:46ID:???Perlで作られた日本語版のWEB CGIゲームを
英語版に改造しようとしているのですが、(作者の許可は取得済み)
作業の進め方がわかりません。
どうしたらいいですか?
二人のチームでやるのですが、
自分が翻訳担当で、もうひとりが技術担当です。
まず日本語の用語を全部リストに洗い出して、
それをかたっぱしから英語に直していって、
翻訳が終わった分から、技術者に渡して、
技術者はできあがった翻訳を受け取ったら、
正規表現か何かでガァーーっと
英語に置換していけばいいのですか?
0784nobodyさん
2006/11/12(日) 01:19:07ID:???0785nobodyさん
2006/11/12(日) 01:34:08ID:???ソースの中の日本語部分を英語に翻訳すればいいだけなのか。
あるいはCGIで生成される日本語も英語に翻訳しなければならないのか、
あと、一つの用語を翻訳して、それを28のファイル全部に
行き渡らせるにはどうしたらいいのか。
0786nobodyさん
2006/11/12(日) 01:46:37ID:???それが難しいってなら、普通にソース中の文字列リテラルを地道に翻訳するしかないだろうね。
0787nobodyさん
2006/11/12(日) 01:55:13ID:???ようはいきなりソース中にべた書きされてる日本語を英語訳するよりも、
「言語パック」
みたいのをつくって、エンジン部分は翻訳者はまったくさわらずに
すむような状況を作ってから、翻訳者に仕事をさせたほうがいいと?
0788nobodyさん
2006/11/12(日) 01:57:45ID:???↑って>>783か?
なんか質問の仕方がなってない。
「〜いのか。」
> ソースの中の日本語部分を英語に翻訳すればいいだけなのか。
他に何かする必要あるのかよ。
> あるいはCGIで生成される日本語も英語に翻訳しなければならないのか
それって「ソースの中の日本語部分を英語に翻訳」じゃないの?
> あと、一つの用語を翻訳して、それを28のファイル全部に
> 行き渡らせるにはどうしたらいいのか。
行き渡らせるの意味が不明。
28のファイルなんて言われてもこっちは知らない。
もし、28個のファイルに同じ用語(日本語)があってそれを
英語に置き換えたいというのなら正攻法でひとつひとつ
やってけ。
もしくは http://akky.cjb.net/download/speeeeed.html みたいなソフト
使って置き換えれば?
> 技術者はできあがった翻訳を受け取ったら、
> 正規表現か何かでガァーーっと
> 英語に置換していけばいいのですか?
技術者なのにそんなことも分からんのかい。
日本語に依存する処理(例えばjcode.plやJcode.pmによる文字コード変換)
をしているところは削ったりとか英語用に変えるとかも必要になったりするでしょ。
■ このスレッドは過去ログ倉庫に格納されています