Perl コーディング初心者質問コーナー Part33
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/03/01 02:46ID:1GeWO7LH【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0652nobodyさん
04/03/20 21:40ID:???フォームからのクエリを %form に取得した後に、
スカラー変数を自動生成して、
スクリプトの記述量($form{})を減らしたかったのが主な理由です。
0654648
04/03/20 21:44ID:???減らさんくて良し。
スカラーにしたら汚くなる&処理の柔軟さを捨てるだけだから。
どーしても自動生成したいなら、>>646のヤツ使うよろし。
誉められた記述じゃないけど、自動生成の中ではそれが一番マシ。
0655638
04/03/20 21:46ID:???今までは
my $name1 = $form{name1};
my $name2 = $form{name2};
…
と記述していたところを、
もっと簡単に定義できないかというのが今回の発端でした。
651さん、、親切に有難うございました。。。
0656nobodyさん
04/03/20 21:52ID:???後で見たとき間違いなく意味不明になるが。
0658未承諾広告※ ◆TWARamEjuA
04/03/20 23:34ID:???0660nobodyさん
04/03/21 02:34ID:???$type eq 'A' or $type eq 'B' or $type eq 'C' or $type eq 'D';
上記の記述なんですが、もうちょい短くならないでしょうか?
$typeと4回書かれているのはなんか俺の感性に反するんですが…。
それだけの理由です。
0661nobodyさん
04/03/21 02:39ID:???感性よりも知識を付けろハゲ
0662660
04/03/21 02:52ID:???scalar grep {$type eq $_} (A, B, C, D);
コスト高いけどこれで(・∀・)
0663nobodyさん
04/03/21 02:55ID:???0664660
04/03/21 02:58ID:???ありが�d。
0665628
04/03/21 11:31ID:???動きますた(=゚ω゚)ノ
他の方々も貴重な情報さんくすこでした(*´Д`)ハァハァ
0666nobodyさん
04/03/21 11:36ID:???何度もチェックする、チェック対象が複雑、などの場合はハッシュを使ってチェックするのが最速。
my %valid_types = map{ $_ => 1 } qw(A B C D foo bar baz);
if($valid_types{ $type }){
# ...
}
0667nobodyさん
04/03/21 15:06ID:???C#の方がいいじゃん。
0670nobodyさん
04/03/21 19:39ID:Bb+Pz/Rr簡単なCGI(例えばHello World等)でテストを行いましたが、エラーの解決法がよくわかりません。
UTF-8(Unicode)以外の文字コードにするとプログラムは正常に動きます。
PerlではUTF-8は一応サポートされていて実際使っている方もいるようですが、
何かうまくいくコツなどありましたらどうかご指南ください。
0672nobodyさん
04/03/21 20:08ID:???「ぱーる」って読むのか「ぴーる」って読むのかわかりにくいってんだろ。
「しーしゃーぷ」は見たまんまだもんな。
0673T.K
04/03/21 20:55ID:???$key に name1 が、 $valに中身があるとして
クエリを分解して読み込むときに
${$key} = $val;
ってやってforeachでループさせれば君のやりたいことはできるよ。
実は俺も長くなるからそうやってたんだけど
やっぱあとあと大変だということがわかった。
PHPに乗り換えようとしたときも変数の取り扱いがちょっと違うだけで
違和感感じてなじめなかった。
おとなしく$form{}でやってたほうがよいよ。
0674nobodyさん
04/03/21 20:56ID:???しーどんぶり、じゃねえの?
0675nobodyさん
04/03/21 21:10ID:???url は うるる、
ってのは、もはや常識ですね
0676T.K
04/03/21 22:36ID:???0678nobodyさん
04/03/21 22:46ID:???0679T.K
04/03/21 22:57ID:???/ ̄ ( ・∀・)⌒\ 待ちくたびれたぞ
__ / _| | |
ヽヽ / / \ | | ,,,,,,,iiiiillllll!!!!!!!lllllliiiii,,,,,,,
\\| |____| .| | .,llll゙゙゙゙゙ ゙゙゙゙゙lllll,
\/ \ | | .|!!!!,,,,,,,, ,,,,,,,,,!!!!|
| ヽ_「\ | |、 | ゙゙゙゙!!!!llllliiiiiiiiiilllll!!!!゙゙゙゙ .|
| \ \――、. | | ヽ .| .゙゙゙゙゙゙゙゙゙゙ |
| / \ "-、, `| | ヽ | |
_/ / "-, "' (_ ヽ ヽ .| |
/ __ノ "'m__`\ヽ_,,,, ヽ | |
`ー― ̄ ヽ、__`/ー_,,,, ゙゙゙゙!!!!!!!lllllllliii| |
\゙゙゙゙゙゙゙!!!!!lllllllliiiii| |
\ ヽ | |
ヽ \ | |
| \.| |
`ヽ、,,_ノ| |
゙゙!!!,,,,,,,, ,,,,,,,,,!!!゙゙
゙゙゙゙!!!!llllliiiiiiiiiilllll!!!!゙゙゙゙
/.// ・l|∵ ヽ\
0680nobodyさん
04/03/22 02:26ID:???ことをしたいので無い知恵絞って以下のような事を考えてみたのですが
これだと予想していないような桁には対応できませんしやり方が不細工かなと思いまして。
いつもは動けばいいが信条なのですがもう少しスマートに書けないか悩んでいます。
数字桁数を操作する関数などがあればいいのですが。お知恵を拝借できないでしょうか?
if ($price <= 999){
$tempPrice = (int($price / 10)) * 10;
}elsif($price > 999 && $price <= 9999){
$tempPrice = (int($price / 100)) * 100;
}
0681nobodyさん
04/03/22 02:32ID:???0683nobodyさん
04/03/22 03:28ID:???$d = 2;
foreach (@n) {
s/(?<=.{$d}).+/'0' x length $&/eg;
print "$_\n";
}
0684nobodyさん
04/03/22 03:29ID:???$1 . ('0' x length $2);
今すごく適当に思いついて作っただけ。
0685nobodyさん
04/03/22 06:57ID:???my $mask = 10**(length($price)-$position);
$price = int($price/$mask)*$mask if ($mask > 0);
0686nobodyさん
04/03/22 08:04ID:???0688nobodyさん
04/03/22 08:43ID:???my $digit = 2;
foreach my $price (@num) {
my $len = length $price;
$price -= $price % (10 ** ($len - $digit)) if $digit < $len;
print "$price\n";
}
>>685
if に頼らずコンピュータの演算誤差なんかで丸めることって出来ませんかね?
0689nobodyさん
04/03/22 09:48ID:UDEoFMoyuse Jcode;
$a="abc";
Jcode::tr(\$a, '0-9A-Za-z', '0-9A-Za-z');
print "Content-Type: text/html\n\n";
print $a;
上記CGIスクリプトが、
E200042 "Not an ARRAY reference at C:/Perl/site/lib/Jcode.pm line 439."
というエラーになってしまいます。なにがいけないのでしょうか。
perl 5.6、Jcode.pmは0.82 です。
このスクリプトは、半角文字を全角にするためのテストで書いたもので、
実際には$a内の全ての半角を全角にしたいです(記号・カタカナ等も)。
そういった処理を一発でできる関数ってのは無いですよね?
0690685
04/03/22 10:41ID:???$maskは0にならないから、if文要りませんでした。
(%演算子では0で剰余を取ろうとして、上手くいきませんね。
if文を消すなら、三項演算子でごまかすという手もありますが、小手先技ですね…)
my $position = 2;
my $mask = 10**(length($price)-$position);
$price = int($price/$mask)*$mask;
>>689
# スクリプトがEUC-JPで書かれているとして
$a = Jcode->new('abc')->tr('0-9A-Za-z', $replacement);
0691nobodyさん
04/03/22 10:43ID:???> $a = Jcode->new('abc')->tr('0-9A-Za-z', $replacement);
$a = Jcode->new('abc')->tr('0-9A-Za-z', '0-9A-Za-z');
でした。
0692689
04/03/22 11:36ID:???# 半角を全角に(英字はさらに大文字に)変換
$jcode = Jcode->new(\$_[0]);
$jcode->tr('0-9A-Za-z', '0-9A-Za-z');
$jcode->tr('a-z', 'A-Z');
$jcode->tr(' !#$%&()=^~\|@`[{;+:*]},<.>/?_-', ' !#$%&()=^ ̄¥|@‘[{;+:*]},<.>/?_−');
$jcode->h2z->euc;
}
>>690を参考にして、関数にしてみました。
オブジェクト指向な書き方をしないとだめなんですね。
これですべて全角になるでしょうか?記号を変換しているところは思いつく記号('と"以外)を
やみくもに列挙しただけで、足りないものがあるかも知れず不安です。
ハイフンは最後にかかなきゃいけないのに気づくのに苦労しました(今後のためのメモ)
また、最後の一行で半角カナを全角にしてるんですが、
「ダ」は「タ゛」になっちゃいますか?と思って実験したら、
ちゃんと「ダ」になりました(今後のためのメモ)。
0693680
04/03/22 12:24ID:fR/XRXq7>>685
なるほど!こういうやり方もあるんですね。悩んでいただけに目からウロコと言うか。
ありがとうございました。スマートだなぁ。
0695nobodyさん
04/03/23 05:07ID:???open (OUT,">$num.dat");
print OUT $buffer;
close (OUT);
として新規ファイル名$num.datに$bufferの内容を書き込むとき、
パーミッションはいくつになってるのでしょうか?
また、こういう風なことをするとき、みなさんex1のようにchmodで変更してると思うのですが、
ex2のようにopenした直後にchmodで変更ってことは出来ないのでしょうか?
(ex1のようにしたくない理由がちょっとありまして・・・。)
#------------------------------ex1
open (OUT,">$num.dat");
print OUT $buffer;
close (OUT);
chmod 0606,"$num.dat";
#------------------------------
#------------------------------ex2
open (OUT,">$num.dat");
chmod 0606,OUT; # これは無理なら chmod 0606,"$num.dat";
print OUT $buffer;
close (OUT);
#------------------------------
ディレクトリなら確か作るときに第二引数でmodeを渡せたと思うのですが、
ファイルは出来ないようでちょっと困ってます。
0696nobodyさん
04/03/23 05:14ID:???http://perldoc.com/perl5.8.0/pod/func/sysopen.html
0700nobodyさん
04/03/23 08:31ID:???my @num = qw/1 -1 11 -11 111 1111 11111 111111 -111111/;
my $digit = 2;
foreach my $price (@num) {
my $len = length(my $p_price = abs $price);
$p_price -= $p_price % 10 ** ($len - $digit) if $digit < $len;
$price = $p_price * ($price <=> 0);
print "$price\n";
}
0701nobodyさん
04/03/23 14:54ID:???0をとり省くのはどのような方法があるでしょうか?
0702nobodyさん
04/03/23 14:54ID:awaWqGNMsub hogehoge{
my @myarray;
(中略)
$myarray[5][0] = 'foo';
$myarray[5][1] = 'bar';
$myarray[5][2] = 'hoge'
・
・
・
}
と同じようなことをpushを使ってやりたいのですが、
どうすればいいのでしょう?
試しに
push ($myarray[5] , 'foo');
のようにやると、
「Type of arg 1 to push must be array (not array element) at」
と怒られてしまいます。
0705nobodyさん
04/03/23 15:00ID:???push @{$myarray[5]}, qw(foo bar hoge);
リファレンスわかってて、なんでデリファレンスわからんかなあ
0707706
04/03/23 15:03ID:???一つ目の引数
0709nobodyさん
04/03/23 16:22ID:???最後に print $template->output;で
ブラウザに表示するのが普通ですが、
これを、HTML全体を変数に格納する方法はないでしょうか?
0710709
04/03/23 16:39ID:???my $foo = $template->output;
でOKですた。。。
0711nobodyさん
04/03/23 17:44ID:???皆さんレス有難うございます。
それで、モジュールは少し理由があって出来れば使いたくないです。
umaskググったんですが説明が、「umask:umaskを設定します」と書いてあり、
だからそのumaskって?感じでした。
で、695で書いたのを、まぁ暴走はしないだろうと思ってレン鯖で実行してみたら、
chmod 0606,OUT;はまぁ無理ですが、
open (OUT,">$num.dat");
chmod 0606,"$num.dat";
print OUT $buffer;
close (OUT);
できちんとパーミッションが606に成ってくれていました。
#因みにchmodをしなければ644でした。
ということなんですが、このままいって大丈夫でしょうか?
いろんなソース見てきましたが、openしてるファイルをchmodしてるのは見たことが無いんですが。
0713nobodyさん
04/03/23 20:42ID:???http://x68000.startshop.co.jp/~68user/unix/pickup?umask
0714nobodyさん
04/03/23 22:17ID:???わざわざ有難うございます理解できました。これ使って出来ますね。
ところで711は問題ないか解るかたいませんでしょうか。
さっきから検索してるんですが、711のようなのが、いいのかだめなのか解らないです。
とりあえず無理なら教えていただいたumaskを使おうと思っているのですが。
かなりしつこくて申し訳ないです。うざかったら放置してください。
0716695,714,....
04/03/24 06:05ID:???んっとややこしいと思ったんで書かなかったんですが、
解りにくいかもですが簡単に書くと、条件分岐してaかbのファイルを開かせ、
別々の処理した後、共通の処理、でクローズといった形で
aの場合だけモードを変えたい。ということです。
つまり、、下のようなソースにaの場合のみchmodを加えたいです。
if ($hoge eq 'a') {
open FH,">a.log";
[aの処理]
} else {
open FH,">b.log";
[bの処理]
}
[共通の処理]
print FH $foo;
close (FH);
もちろんcloseの後にもう一度条件分岐で大丈夫ですが、
不可能で無い限りopen中に入れたいなと思いました。
0718nobodyさん
04/03/24 16:17ID:???1. ハッシュの要素を全て削除したい。
2. http://www.rfs.co.jp/sitebuilder/perl/02/05.html
によれば、%hash = (); でできるようなのですが、Win32 + ActivePerl 5.8.0 で
できませんでした。以下、実験したスクリプトです。
$hash['a'] = "ABC";
%hash = {};
%hash = ();
$hash = ();
$hash = {};
print $hash['a'];
3. エラーは出ませんが、"ABC" と表示されてしまいます。
0719718
04/03/24 16:19ID:???$hash{'a'} = "ABC"; で解決しました。
0721nobodyさん
04/03/24 18:39ID:???0723nobodyさん
04/03/24 19:57ID:???0725nobodyさん
04/03/24 20:39ID:6j96YsNkPerlで日記を作ってる最中です。
一番下に、1 2 3 ・・・・ 11 12 と月別のリンクを作って、
番号クリックしたらその月の日記を見れる、、、って感じで。
クリックしたらその番号を変数に入れて、日記のログ出力のルーチンに飛ばすみたいな事できますか?
できるならどういうテクを使うんでしょうか?
0729725
04/03/24 21:48ID:6j96YsNkログファイルから、クリックした数字の月だけのログを出力したいんです。
0730nobodyさん
04/03/24 21:59ID:???そこらへんに転がってる日記スクリプトとか、
なんならいわゆる「ページ移動」が可能な掲示板スクリプトでも調べれば
ヒントを得られると思う。
0731nobodyさん
04/03/24 22:55ID:???!$scr と $scr eq 0 が違うのは文字と数字の判断の違いでnull値が入るのは
わかったのですがよくこういった比較演算子?で混乱してしまいます。
よろしければ教えて頂けないでしょうか?
0732nobodyさん
04/03/24 23:01ID:???正確に書きたいなら $scr == 0 もしくは $scr eq "0" な。
0733nobodyさん
04/03/24 23:29ID:???その日記スクリプトにハイパーリンクで月選択ができる場合
href="./diary.cgi?month=1"といったように、GETのみとなるのでしょうか?
0734nobodyさん
04/03/24 23:33ID:???リロードとかするたびにダイアログでてウザいだけかと。
0735nobodyさん
04/03/25 00:04ID:O9PiycAhインラインフレーム内にCGIを表示させて、そのCGIのどこかの変数に、値を代入したいんです。
具体的に言うと、
<IFRAME SRC="data.cgi?value">
として、valueをどこかの変数に入れることはできますか?
いろいろなサイトを見て、
read(STDIN, $val, $ENV{'CONTENT_LENGTH'});
こうすれば、$valにvalueが代入されるという話を聞いたんですができませんでした。
(何も代入されていませんでした。)
誰かわかる人がいたら教えてください。
よろしくお願いします。
0736nobodyさん
04/03/25 00:16ID:???そりゃPOSTの場合だ。
GETとPOSTの違いを勉強汁。
0737nobodyさん
04/03/25 01:25ID:???cgi-lib.pl使ってるよ。
エロイ人たちは容量を最低限に抑えるために中に書き込んでるの?
0738nobodyさん
04/03/25 05:23ID:???でも俺はフォームからの受け取りくらいは
そう面倒でもないし簡単だから大概自前。
0739nobodyさん
04/03/25 08:01ID:???for (5 .. 0) { print;}とするとダメですよね
で
reverseをつかって
for (reverse 5 .. 0) { print;}
なら出来ると思うんですが、この方法は妥当でしょうか
0740nobodyさん
04/03/25 08:24ID:???for (reverse 5 .. 0) { print;}
↓
for (reverse 0 .. 5) { print;}
0741nobodyさん
04/03/25 09:02ID:???for ($start < $end ? $start .. $end : $end .. $start) { ... }
0744nobodyさん
04/03/25 10:18ID:???ていうか何故そんな値で回したいのかよく分からんのだが。
0745nobodyさん
04/03/25 10:33ID:???もういいです。
0746nobodyさん
04/03/25 11:06ID:sU+YK1M2(中略)
return (%hPGTname2PTCid, %hPGTname2PTTid);
}
my (%hPGTname2PTCid, %hPGTname2PTTid) = &hoge;
として2つのハッシュ配列を取得したいのですが、
前者のハッシュ配列しか取得できていない模様です。
どうすれば2つのハッシュ配列を取得できるのでしょうか?
0747nobodyさん
04/03/25 11:09ID:w7s8ctdp#!/usr/local/bin/perl
print "Content-type:text/plain\n\n";
print "CGIのテスト\n\n";
sleep(3);
print "3秒後";
exit;
と、書くと「CGIのテスト」と「3秒後」が実行後3秒してから同時に表示されてしまいます。
色々見てみましたがよく理解できません。
命令はプログラムの上から順に実行されると思い込んでいたんですがそうではないんですかね。
こうゆう基本的なことを自分で解決するのに良いウェブサイトや本はありますか?
よろしくお願いします。
0748nobodyさん
04/03/25 11:18ID:???でいいだろ。
for (my $i = 5; $i >= 0; $i--) {print;}
とか。
0751nobodyさん
04/03/25 11:21ID:???http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlsub.html#Pass_by_Reference
>>747
http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlfaq5.html#How_do_I_flush_unbuffer_an_outpu
■ このスレッドは過去ログ倉庫に格納されています