Perlコーディング初心者質問スレ Part 40
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001nobodyさん
05/01/27 18:08:42ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0830nobodyさん
05/03/03 18:01:27ID:???0831827
05/03/03 18:32:46ID:???>>828は一度に@_に入れてるんですよね?
使い所によっては便利ですね。勉強になります。
>>829
改行が無い場合は何もしないんじゃなくて0を返してたんですね
改行が無い場合は何もしないと間違って憶えてました
828さん、829さんありがとうございました
0832nobodyさん
05/03/03 20:42:46ID:F2b+bV+tOui.
もし、chompの後に$_で一つずつ処理をするのならば
@_ = <IN>;
chomp @_;
while ($_ = shift @_)
{
〜
}
という事もできます。
0835832
05/03/03 21:11:20ID:F2b+bV+tあ、本当だ。スマソ
0836nobodyさん
05/03/03 22:01:20ID:???0837nobodyさん
05/03/03 22:58:04ID:???sub my_chomp($);
while(my_chomp <DATA>){
...
}
exit;
sub my_chomp($)
{
$_ = shift;
chomp;
return(defined $_);
}
0838829=833
05/03/03 23:52:40ID:???結局、定石通り (>>827 の最初のやつ) にするのがベストだと思うようになった。
0839nobodyさん
05/03/03 23:59:42ID:Q1wNh1eiなぜでしょうか?(改行押すと送信になる)
データが壊れてしまうので、改行が入らないようにしたいのですが
どうすればいいでしょうか?よろしくおねがいします。
0840nobodyさん
05/03/04 00:22:07ID:???ん?
0841nobodyさん
05/03/04 01:13:12ID:???なぜ改行が入ったかは確かに謎だが、たぶん Perl コーディングに関係ない原因だとは思う。
コーディングで解決するなら >>840 みたいにするんだろうなあ。
>>840
それって入力が元々 $_ に入ってるんであって、決して ~ が抜けてるわけじゃないよな?
0842nobodyさん
05/03/04 01:17:56ID:???$_自体が書き換えられる
0843nobodyさん
05/03/04 01:24:24ID:???何故入るのかは分からないが、それによって壊れるようなプログラムを書くのは良くない。
取得したデータから改行を取り除くほうが安全だぞ。
0844839
05/03/04 04:55:51ID:???ありがとうございました。
842の意味がよくわからなかったのでとりあえず
$hoge =~ s/\n//g; を入れてみました。
自分でバグが再現できないので、有効なのかはわかりませんが。。
>>843
うーんまだよく方法がわかりませんでした。CGIで
data<>data<>message message message<>data<>
data<>data<>message message message<>data<>
このように保存してるデータで、一つだけ
data<>data<>message message message<>data<>
data<>data<>message message
message<>data<>
こうなったため、表示が壊れるという感じでした。
初めて自分で1から書いたので・・・
0846nobodyさん
05/03/04 09:14:20ID:???0847nobodyさん
05/03/04 10:13:02ID:???・・・意図的に送りつけるのは簡単だが。
ファイルへ書き込むまでにいろいろ処理してるでしょ?
処理途中で改行が紛れ込んでしまうことだってある。コーディングミスで。
再現性を確立しないと追いかけるのは難しいなり。
0848nobodyさん
05/03/04 12:05:01ID:???君はXSSってのを少し勉強したほうがいいよ。
相手が送ってくるものは全てウイルスと思え。
その上でウイルスが送られてきても大丈夫なように作らないと、君のサイトが
ウイルスの配布元になったりするかもしれない。
まあウイルスってのはおおげさだけどね。
0849nobodyさん
05/03/04 12:35:30ID:???iniファイルのままサーバに置いておくと、
ブラウザで見たときに「ファイルの保存」ダイアログが開かずに、
iniファイルの中身が見えてしまいます。
「右クリックして保存しろ」などの注意文を書く、という手もありますが、
せっかく投稿ということで掲示板的CGIも作っているのでCGIを通すことで
ダイアログを開かせることにしました。
CGIはContent-Typeにtextと入れると広告が入るとかでちょっと苦労しましたが、
なんとかダイアログを出させて、正しい中身を送信できるようになりました。
しかし、ここで微妙な問題が残りました。
ダイアログを開いた時のデフォルトのファイル名が、「〜〜.cgi」になってしまうのです。
なんとかして.iniにできないかと調べているのですが、
御存じの方がいらっしゃいましたらお願いします。
# ファイル名が指定できなかったらCGIを通すのはやめて注意文方式にするつもり。
0851nobodyさん
05/03/04 13:11:12ID:???print "Content-Disposition: attach; filename=$file_name\n\n";
とか
0852nobodyさん
05/03/04 13:34:06ID:???windowsXPなどで画像・動画ファイルを選択して切り取りして上の階層に貼り付けるみたいな感じです。
普通に
open FH,"$filename";
my @file = <FH>;
こういう感じでバイナリーファイルも問題なくコピーできるんでしょうか?
それとも何かオススメのモジュールがありますか?
0853852
05/03/04 13:41:24ID:???どうすればいいんですか?
0854nobodyさん
05/03/04 13:42:11ID:???>>852 rename でだいたいうまくいく。うまくいかない場合はFile::Copyモジュールのmoveメソッド、だってさ。
0855852
05/03/04 14:07:07ID:???renameでできました。カレントの中にあるディレクトリ名だけを配列に入れたいんですが、
なにか言い方法はないでしょうか?
globでできるのかなと色々試してますが、ディレクトリだと判断できません。
0856852
05/03/04 14:16:19ID:???判断できないのかな。。。。
0857nobodyさん
05/03/04 14:16:27ID:???ちなみにディレクトリ内全部見る場合 readdir のほうが glob "*" より効率的らしい。
0858nobodyさん
05/03/04 14:37:52ID:???$str =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
これでエンコード(?)したやつを元に戻すのはどうやればできるんでしょうか?
とりあえず反転して
$str =~ s/pack("C",hex($1))/%([0-9a-fA-F][0-9a-fA-F])/eg;
とやってみたんですがダメでした(当然かな・・・)
0859852
05/03/04 14:39:42ID:???#京
# ディレクトリ名だけ取得
my @dirs;
foreach (glob "*"){
if ( opendir DIR,"$_") { push @dirs,$_; closedir DIR; }
}
my @files;
foreach (@dirs){
my $dir = $_;
foreach (glob"$dir/*"){
my ($file) = m{^[^/]*/(.*?)$};
rename $_,$file;
}
}
open FH,">test.txt";
foreach (@files){
print FH $_,"\n";
}
close FH;
print "content-type:text/html;charset=euc-jp;\n\n";
色々試してる間になんとなくでこれを実行したらデスクトップにあったファイル・フォルダが全て
壊れたのかどこかに移動されてしまいましたorz
今かなりあせってます。
これはtest.plという名前でデスクトップ直下の画像ファイルを収納しているフォルダに
いれてましたので、その外側に影響を与えるはずはないからと安心してたのですが・・・・
本気でやばいので助けて下さい。元に戻す方法はないでしょうか。
0861852
05/03/04 14:52:31ID:???perl -c をやるつもりでそれをなしでtest.plを実行させてしまったので、
そのときのカレントディレクトリである
C:\Document and Settings\a
でこれを行ってしまったようですorz
最悪です。こういうことの修復はもう手動でしか出来ませんよね?
それでしたらパソコン初心者板に行って聞いてこようと思うのですが・・・
0862852
05/03/04 14:57:54ID:???もしも1発で回復する方法などありましたら・・ってそれじゃマルチになっちゃうか。
とにかくすみません。行って来ます。
0864nobodyさん
05/03/04 15:24:38ID:???プログラムに誤りがなければアクセスログを見て書込んだブラウザを追い掛けてみるといい。
ネスケ4以前とか一行テキストボックスにコピペで改行コードを含めたりできる。
他にもスクリプト経由で改行を含めたデータを送りつけられたりできるし
フォームページをパソコンにダウンロードしてフォームを改竄して送りつけることもできる。
テキストエリア意外のデータでも改行コードのエスケープ処理をするのは良い方法だ。
Perlコーディングとは関係ない話なのでこれまで。
0865852
05/03/04 17:06:39ID:???とりあえずフォルダ命をしっかり指定したこれからはやります。
0866852
05/03/04 17:14:04ID:???しかしこれの式ってOS依存なんですよね?
windowsXPですが、
C:\Documents and Settings\a
こういうディレクトリをglobに渡したいのですが、
glob "/Documents and Settings/a";
これではダメなようでどうやら半角スペースがダメみたいです。
半角スペースのマッチはどうするんですか?
それとこれはテストはwinXPですが実際にはlinuxなのです。
やはり互換性がありませんか?
";
0867nobodyさん
05/03/04 18:57:04ID:Xe71hSRxdbmopenを使うと、サーバはどのDBMを使っているのでしょう?
サーバ次第だと思いますが、何か設定箇所か法則性があれば
教えてください。
また、DBM次第で拡張子(db, pag, dir)がいくつかありますが、
このDBMは必ずこの拡張子という決まりはあるのでしょうか?
別サーバへのDBMファイル移行で詰まっています…
0868nobodyさん
05/03/04 19:00:20ID:???print <<EOM;
と
print <<EOF;
の違いって何ですか?
0871nobodyさん
05/03/04 20:38:45ID:???巷に配布されてるスクリプトにShift_JISが多いのは何故ですか。
Shift_JISで書くことで何か旨みがあるのですか?
0872nobodyさん
05/03/04 20:47:03ID:???0873nobodyさん
05/03/04 20:55:48ID:???0874nobodyさん
05/03/04 21:14:36ID:???0876nobodyさん
05/03/04 22:26:35ID:???$a =~ s/<br>/\n/g;
これをどう変えればいいですいか?
0877nobodyさん
05/03/04 22:40:30ID:???Windowsの「メモ帳」がShift_JISにしか対応してないことと、
テキストエディタ上で設定する必要があることに起因しているようですね。
ありがとうございます。
0878nobodyさん
05/03/04 23:28:05ID:???http://www.perldoc.com/perl5.8.0/pod/func/dbmopen.html
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perltie.html
http://www.att.or.jp/perl/man/anydbmfile.3pm.html
0880nobodyさん
05/03/05 00:22:28ID:???globの半角スペースは、OS依存でなくglobの仕様
glob '/usr/*/*/* /bin/* /etc/*/*';
という記述もできるようになっている。
半角スペースをファイル名の一部とみなしてほしい場合は
半角スペースの直前にバックスラッシュ(円マーク)を記述して
エスケープすればよい。
0881nobodyさん
05/03/05 02:58:35ID:hbhM7+40まずグーグルの使い方を覚えようね。
http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=%E6%94%B9%E8%A1%8C%20%E5%A4%89%E6%8F%9B+textarea&num=50
0882nobodyさん
05/03/05 09:42:12ID:???エロい人おしえてください
0883852
05/03/05 11:08:25ID:???エスケープは何度も試したんですが・・・・
どうやらシングルクォートでやらないといけないようですね。
"/Documents\ and\ Settings/a/*"
これではダメで
'/Documents\ and\ Settings/a/*'
これだといけました。そうなってくるとperlとしては半角をエスケープしてないことに
なるんだけどな・・・よくわからん。
0885nobodyさん
05/03/05 12:34:00ID:???ダブルクォートだと glob に渡る前にエスケープが解釈されちゃうだろ。
sub hd { join ' ', map uc unpack('H2', $_), split //, $_[0] }
print hd("/Doc\ and\ Set/a/*"), "\n";
print hd("/Doc\\ and\\ Set/a/*"), "\n";
print hd('/Doc\ and\ Set/a/*'), "\n";
0886nobodyさん
05/03/05 14:24:31ID:???jcode.plがUnicode非対応。
自力でやるにも文字コードの判別、変換が困難。
Perl5.8以降限定や、Jcode.pm必須にするか、
文字コードのチェックを行わなければ大丈夫だろうけど、
そこまでしてUTF-8にこだわる理由が見出せない。
でも、XHTMLが主流になれば、移行していくと思うよ。
0887nobodyさん
05/03/05 14:38:07ID:???配布するスクリプトはまあいろいろ難しいだろうな
0888nobodyさん
05/03/05 15:02:07ID:???$tmp = 'http://foo/bar/1234.jpg';
$pat = '(.*)\.jpg';
$rep = '\1.png';
$tmp =~ s/$pat/$rep/;
print "$tmp\n";
これだと、「\1.png」としか表示されません。
置換の所を、
$tmp =~ s/$pat/\1.png/;
にすれば期待通りの結果がでますが、どうすればいいのでしょうか。
パターンも置換文字列も変数を使用したいです。
0889nobodyさん
05/03/05 15:02:38ID:???0890nobodyさん
05/03/05 15:26:50ID:???メモ帳で UTF-8が開けるの初めて知ったよ(Win2000)
でもデフォはSJISだから95とかMeが廃れても無理っぽい。
0891nobodyさん
05/03/05 15:36:58ID:???スクリプト開発者はさすがにメモ帳デフォのままでコーディングしないっしょ?
0892nobodyさん
05/03/05 16:06:25ID:???$tmp = 'http://foo/bar/1234.jpg';
$pat = '(.*)\.jpg';
$rep = '$1.".png"';
$tmp =~ s/$pat/$rep/ee;
print "$tmp\n";
0894nobodyさん
05/03/05 17:11:23ID:???自分しか使えないスクリプトほどくだらないもんはない。
誰でも使えるものを作れるかどうかが、馬鹿とアホの分かれ道なわけで。
そもそもヘタレが多すぎだな。
環境によって書き換えてもらわないといけないなんてアホくさい。
普通は設定ファイルは別途にしておいて、その設定ファイルをいじるための
インターフェースも作っておく。
プログラムなんてのは他人に書き換えてもらう事を前提にするようなもんじゃない。
想定をこちらで決めてしまわなければどうしようもない。
0895nobodyさん
05/03/05 17:15:36ID:???重いとか聞いたのでまだ使ったことありません。
それにテンプレートを作るってことは変数が乱立せざるを得ないし、
構文を埋め込みok状態で使うならテンプレートファイルを別に作る意味も不明。
とか思ってるんですが、使用されてる方の意見を利かせて下さい。
今は基本的にHTMLはプログラム内にあります。まあ出力内容を作成する
ルーチンなので外部に置いてもなんら問題はありませんが。
逆に差がないなら分ける意味もないですうしね。
0896nobodyさん
05/03/05 18:58:05ID:???仕事で作る奴はちょろちょろ変更あるのでテンプレートで分けるように
なった。しょうもない文章の修正とかでいちいち本体いじるのうっとう
しいと思ってたのでなかなかよろしい。
で、慣れるとプログラムがすっきりするので、個人で作るような
のもテンプレ使ってたりします。
テンプレライブラリは重いといえば重いんだけど、1ページの表示が
遅いってほどじゃないので、気にすることないと思う。
0897nobodyさん
05/03/05 19:06:00ID:???メチャクチャなので使う気になれないんだよな。
きちんと変換表が統一される夢のような時代は絶対来ないけど
たぶんそのうちunicodeの変換表の有力な奴相互に判定/変換する
ようなライブラリができるだろうからそれ待ち(笑)
0898nobodyさん
05/03/05 19:27:37ID:???そもそも文字コードなんて商売上の理由なんだろうから歩みよりはないだろうし。
俺はこれからもSJIS使っていくぞ。
0899nobodyさん
05/03/05 19:29:22ID:???俺の場合だと hash や array にぶちこんで渡すので変数が乱立するってことは無い
DBI の fetchrow_hashref で取ってきた hash をそのまま Template に渡してはいおしまい、みたいな感じで
お蔭でプログラムの見通しが断然良くなった
正直 Template 使わない CGI はもう書きたくない
普通は重いんだろうとは思うが、俺んとこは mod_perl 環境なので、
パース済 Template のキャッシュも効いて、全然重さを感じない
0900nobodyさん
05/03/05 20:03:51ID:???0901nobodyさん
05/03/05 20:55:09ID:???例えば、ある顧客のデータと、管理者のデータを一度に表示したい時、
{
client_name => 'hoge', client_address => 'foo',
admin_name => 'hage', admin_address => 'bar',
}
とかで渡してやらんとだめだ。
{
client => { name=> 'hoge', address='foo' },
admin => { name => 'hage', address='foo' },
}
とかじゃだめってことね。
この点Template-Toolkitは偉すぎる。
0902nobodyさん
05/03/06 09:56:09ID:???ちょっとでもスクリプト軽くしたい一心から、
HTML::Templateは問題外と思っている。
HTML::Templateを、数万回/day呼ぶとやっぱ重いかな?
0904nobodyさん
05/03/06 13:35:38ID:???0905895
05/03/06 13:41:02ID:???私的にはhashやarrayの中に入れることも乱立だと思ってます。
プログラムの見通しは現状でずいぶんいいんですよね。
開始100行部分辺りがプログラムの流れで細かい処理はルーチンを下のほうに作って
あって、そいつらはグローバルをいじることはできなくしてあるし。
間違っても全体の流れてきな処理と個々の処理を同列視しないように作ってます。
こういうやり方にしてから拡張もいくらでもできるようになったし。
でも皆さんなかなか評判がいいようなのでちょっと遊びスクリプトを作る時には
使ってみようかな。ありがとうございました。
0906nobodyさん
05/03/06 14:50:24ID:???すごく同意 なので私は
$ref->{aaa}->{bbb}を$hash{'aaa-bbb'}に変換する関数を作って使ってます。
$change->{form_data} = \%form_data;
とかが出来るようになって幸せ
0908nobodyさん
05/03/06 16:13:12ID:???ただの構造化で満足している人がTemplateを使えるとは思いませんが。
そもそもビューを切り離すことにメリットを感じない程度の小規模スクリプトしか
書いてないんでしょうから。
0909nobodyさん
05/03/06 16:18:15ID:???まあ使ってみて目覚めるということもあるから、生温かく見守ってあげようや
漏れも頭ではMVCとか知ってたけど、実際にモノを作ってみるまで恩恵がわからんかった
0910nobodyさん
05/03/06 17:13:17ID:???まあこのスレのレベルではしょうがないか。
0911nobodyさん
05/03/06 17:48:51ID:???Templateを単純なコード埋め込み可能テキストくらいにしか使えてないんだろうな。
かわいそうに。
0912nobodyさん
05/03/07 02:01:45ID:???Templateは置くだけじゃ使えないよね?
しかたなくHTML::Template派。
0913nobodyさん
05/03/07 02:03:59ID:dh8KtD970914nobodyさん
05/03/07 02:12:46ID:???syntax onを忘れずに
0917nobodyさん
05/03/07 04:10:46ID:???確かにSTDINの内容を渡しちゃうのはキモいけど
my $cgi = new CGI();
my $template = HTML::Template->new(scalarref => \$html, associate => $cgi);
とかよく使われてる手法じゃない?
0919nobodyさん
05/03/07 08:07:45ID:???$template->param(%form_data);
としてクライアントにテンプレートの変更権限が無い場合
%form_dataが例え汚染されていたとしても
重大な影響は与えないと思う。
とはいえ
hoge.cgi?mail=危険なタグ
とかされた場合、ブラウザクラッシュとかもありえるから
サニタイズは必要ですね
0920nobodyさん
05/03/07 09:27:19ID:???一応、出力時にエスケープできるオプションもある。
>>919
http://www.google.co.jp/search?q=XSS
0923nobodyさん
05/03/07 18:44:45ID:???perlソース側ではprint文、HTMLタグは一切記述せず(httpヘッダくらいはいいかな)
テンプレート側だけで対応する事になるのでしょうか。
速度や保守性を考えるとどのぐらいの割合がいいのかなと思いまして。
0924nobodyさん
05/03/07 19:55:37ID:???基本的に表示のための加工処理はテンプレートに集中させるべきだと思いますが。
ヘッダは本体スクリプトで。
0925nobodyさん
05/03/07 20:36:15ID:C7YlD7f8$remolog = './remolog.cgi';
のように./をつけているのを多く見ます。
./に何か御利益があるんですか?
0926nobodyさん
05/03/07 23:25:57ID:iIlEY0AB【やりたい事】
methodが post と get と 何もなし で分岐させたい。
【やってる事】
if( $ENV{'REQUEST_METHOD'} eq "GET" ){
hogehoge
}elseif( $ENV{'REQUEST_METHOD'} eq "POST" ){
hagehage
}else{
punipuni
}
【困った事】
エラーになります。分岐を2つ(GET と else、 POST と else)
にするとなぜかエラーになりません。
原因はなんなのでしょうか?よろしくお願いします。
0928926
05/03/07 23:32:09ID:???解決しました。ありがとうございました。
0929nobodyさん
05/03/08 00:18:06ID:???else if
とか
for(i = 0
とかやっちゃう
レス数が900を超えています。1000を超えると表示できなくなるよ。