トップページphp
1001コメント364KB

Perl コーディング初心者質問コーナー Part36

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん04/07/14 13:23ID:???
いらっしゃーい、Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
072471104/08/14 18:15ID:???
>>718

@a = qw/1 2 3 4/;
$a = "absnd";
%a = (a => 1);
(%a , $a , @a) = undef;
print "$a\n",%a,"\n@a";

これだけできました。でも一応
(%a , $a , @a) = (undef) x 3;
とかしたほうがいいですか?
0725nobodyさん04/08/14 18:17ID:???
どんぐりの背比べが始まったw
0726nobodyさん04/08/14 18:19ID:???
>>716みたいなのに限ってcgi.pmを使っている(w
0727nobodyさん04/08/14 18:22ID:???
>>726
何その妄想
0728nobodyさん04/08/14 18:34ID:???
>>723
文法チェックだけでは済まない問題も、use strictによって
解決できること分からないバカは(ry
0729nobodyさん04/08/14 18:36ID:???
飯食いながら左手で打ってたら「も」が抜けちゃったYO
0730nobodyさん04/08/14 18:44ID:???
夏満開
0731nobodyさん04/08/14 19:08ID:???
>>724
(%a, $a, @a) = ();
0732nobodyさん04/08/14 19:15ID:???
(>>1-1000) = undef;
0733nobodyさん04/08/14 19:19ID:???
>>732
だから、リストコンテキストにスカラーコンテキスト代入してどうするよ!
0734nobodyさん04/08/14 19:25ID:???
あんでふとーっ!
0735nobodyさん04/08/14 19:33ID:???
(´-`).。oO(>733 = '逝ってよし';だな)
073672404/08/14 19:33ID:???
>>731
それでもできるんですね。
>>733
代入できても、やってはいけないことなのでしょうか?
(%a , $a , @a) = (undef x 3);
これが一番ですか?
0737nobodyさん04/08/14 20:37ID:???
>>733
コンマ演算子の優先順位が代入演算子より低いから括弧で括る必要が
あるのであって、代入する要素が一つの場合はわざわざリストにする
必要はない。つまり @a = 'a'; は @a = ('a'); と等価。

>>736
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perldata.html#List_value_constructors

(%a, $a, @a) = undef; は %a = (undef), ($a, @a) = (); と等価。
(%a, $a, @a) = (undef x 3); は構文エラー。
(%a, $a, @a) = (undef() x 3); は %a = (undef), ($a, @a) = (); と等価。
(%a, $a, @a) = ((undef) x 3); は %a = (undef, undef, undef), ($a, @a) = (); と等価。
0738nobodyさん04/08/14 20:43ID:???
>>736
もまえは何がやりたいんだ?
(%a , $a , @a) = (undef x 3);
には少なくとも2つの大きな間違いが存在している。

まず、第1にundef x 3は文法エラーとなる。内容は実際に実行してから読め。
そして第2に、
(%a , $a , @a) = (1 => 2, 3, 4);
がどうなるのか考えろ。
0739nobodyさん04/08/14 20:46ID:???
しかしすごいなあ。
use strictの有用性を説明されても聞かないくせに、
自分の質問にだけは答えてもらおうとする。
さ す が 夏 休 み
0740nobodyさん04/08/14 21:08ID:???
そうか、>>707>>711は同一人物だたのか。
0741nobodyさん04/08/14 21:41ID:???
夏休みに買うような本に載っているスクリプトはuse strictしたら
まったく動かない事くらい察してやれよ。
0742nobodyさん04/08/14 21:49ID:EgOE5Yt9
>>739
最初は釣りかと思ったが真性包茎みたいだねw
0743nobodyさん04/08/14 21:58ID:???
つーかずっとuse strictつけるとか思ってる奴ってww
簡易デバッガみたいな使い方だろ、use strictって
0744nobodyさん04/08/14 22:01ID:???
>strict.pmとかvars.pmとか色々読み込むので確かに遅くはなりますが、

っていうか、人間の感覚じゃまずわからんだろ。
strictは結構効率良いみたいだ。
Benchmark測ればわかる。

そんなことより、速度が遅いとか、無駄とかアフォとか言う前に、基本を勉強するべ
きで、しかもuse strict;の必要性についても、もっと勉強したりここの上級者の言
うことを信用したりしろっての。
0745黒死犬 ◆EgxBlf8nvc 04/08/14 22:38ID:???
warnings に助けられたことはあるけど、strict は五月蝿いだけかも・・・
従わなかったところで、挙動が変わるわけでは無いし

http://perldoc.jp/docs/perl/5.8.1/strict.pod
0746nobodyさん04/08/14 22:55ID:???
my付けるのと付けないので挙動が変わったりするよ
0747nobodyさん04/08/14 23:00ID:???
use strict って擬似的なモジュールが存在するけど、実際はperlの内部で
完結してるんじゃないの?

まあuse strictと書きたくないなら
$^H |= 2|0x200|0x400;
とでも書きなさいっと。
0748nobodyさん04/08/14 23:01ID:???
use strict;なんてリリース時にはコメントアウトすればいいだろ。
0749nobodyさん04/08/14 23:04ID:???
>>748
いやそれが普通の使い方じゃないか?
ずっとuseしてる奴なんか居るのか?
0750黒死犬 ◆EgxBlf8nvc 04/08/14 23:11ID:???
>>746
ああ、my変数の typo を教えてくれるという重要な機能がありましたね・・・

sub unko {
 my $unko = shift;
$$unchi = $$**$$; # $$unko (ry のつもり
}
0751nobodyさん04/08/15 00:17ID:ThpZR4Ya
先ほど間違ってphpの方で質問してしまいました...
C-BOARDで、投稿画面に追加したセレクトボックスの
投稿データチェック(未選択不可)を行いたいのですが、
どうすればいいのですか?

下記のところに、新しく追加したら大丈夫だと思うのですが..
チェックの仕方がわかりません。

#── メールアドレスをチェック
length($::FORM{'email'})
&& ($::FORM{'email'} !~ /^[!-?A-~]+@[!-?A-~]+\.[!-?A-~]+$/)
&& push(@error, 'メールアドレスが不正です。');

#── パスワードをチェック
($::FORM{'key'} =~ /[<>&"]/)
&& &::error(\('パスワードに「<, >, &, "」は'
. '使えません。'));
0752nobodyさん04/08/15 00:33ID:???
>>749
めんどいから use strict つけたままだけど
俺んとこは mod_perl だから実行時の速度は変わんないし

しかし珍しく本当に「コーディング」の話題だなあ
0753nobodyさん04/08/15 00:49ID:???
>>751
■ 自分で改造するアドバイスが欲しい場合には
★三 【 スクリプト改造工房 PART 8 】 ★三
http://pc5.2ch.net/test/read.cgi/php/1077525387/79(テンプレ)
0754nobodyさん04/08/15 00:57ID:3zveFoKh
↓のように記述して、csvファイルからデータを読み出したのですが、
読み出した文字列が文字化けしたままなのです。
&jcode'convertで文字コードが変換出来ていないようなのですが・・・
どこが原因なのか、良くわからないのです。
お手数ですが、教えてくださいまし。

require "jcode.pl";

open(FI,"aaa.csv") || return 0;
while(<FI>){
$_ = nkf("-ed",$_);
chomp();
split(",");
if($_[0] eq $bbb){
$ccc = $_[1];
&jcode'convert(*ccc, "sjis");
}
}
close(FI)
0755nobodyさん04/08/15 02:36ID:???
>>751
まずC-Boardのあるディレクトリを削除する。
075675404/08/15 06:40ID:3zveFoKh
すいません、解決しちゃいました。板汚しスイマセン・・・
075772404/08/15 11:33ID:???
>>737-738
とりあえず一回で10個くらいの変数(スカラ、アレイ、ハッシュ入り乱れてます)をundefして
メモリを開放したいんです。

($a,@a,%a) = ();
これで完全に未定義の時と同じメモリ状況になるんですか?一応消えるのは確認しましたが。
0758nobodyさん04/08/15 12:03ID:???
>>757
ならんて。
$aは未定義になるがメモリとは関係なし。
@aと%aは要素がない状態になるだけで、それまでに確保したメモリはそのまま。
ちなみにPerlは最初にある程度のメモリを確保して変数領域に使ってるので
undef @aするとその分の変数領域は解放されるが、システムリソースとしては
喰われたままでPerlが終了するまで解放されない。
過去ログ嫁
075972404/08/15 13:05ID:???
>>758
>$aは未定義になるがメモリとは関係なし。
>@aと%aは要素がない状態になるだけで、それまでに確保したメモリはそのまま。
>ちなみにPerlは最初にある程度のメモリを確保して変数領域に使ってるので

Perlではundefしてもメモリの開放はできないから、メモリ開放を期待して
ちょこちょこundefする必要はないってことですね。
0760nobodyさん04/08/15 14:37ID:???
ageておこう
0761ぢおぢお04/08/15 15:24ID:EbxomzZw
ifを使ってもしファイルがあったら〜の処理をするというのをしたいんですが
ファイルがあったらというのはどうやってすればいいんですか?
0762nobodyさん04/08/15 15:28ID:???
>761
ファイル検査演算子を使う。
0763nobodyさん04/08/15 15:31ID:???
演算子だらけのperl
0764ぢおぢお04/08/15 15:33ID:EbxomzZw
osがwindowsなので前やってみても駄目だったんです
0765nobodyさん04/08/15 15:36ID:???
>764
何をやってダメだったか書いてみ。
winだからって全てのファイル検査演算子が使えないわけじゃない。
tu-ka,環境依存の話なら先にそれを言え。
0766nobodyさん04/08/15 15:54ID:???
なにをやってもダメなやつっているよ
0767ぢおぢお04/08/15 15:56ID:EbxomzZw
if ( -e "$hozon" ) {
print "存在\n";
}
という風に存在したらというのをやったらなりませんでした
0768nobodyさん04/08/15 16:04ID:???
if (-e $hozon) {
0769ぢおぢお04/08/15 16:19ID:EbxomzZw
できました。ありがとうございました
0770nobodyさん04/08/15 16:39ID:LDNVI8I+
tesa
0771ぢおぢお04/08/15 17:11ID:EbxomzZw
if (-e "./nakama/$in{'id'}.cgi") { }
のようなやつで
何々と何々と何々が読み込めたらという処理はどうすればいいんですか?
すみません検索しても分からなかったので
0772nobodyさん04/08/15 17:29ID:???
>>771
そ   ん   な   お   前   が
や   り   た   い   こ   と 
直   接   の   サ   ン   プ   ル   は   な   い


$aと$bと$cが1以上ならという処理はどうすればいいんでしょうか。

考える気がないだろ。
0773nobodyさん04/08/15 17:30ID:???
>>771
@hozonに全部パスを入れとけアフォ

foreach(@hozon){
print "ok" if -e $_;
}

このクソアフォが!?
0774nobodyさん04/08/15 17:32ID:???
>>773
っていうか
print "ok" if grep {-e $_}@hozon;
だったな。
0775nobodyさん04/08/15 17:37ID:???
print "ok" if (grep {-e $_}@hozon) == @hozon;
0776ぢおぢお04/08/15 17:44ID:EbxomzZw
見ても全然分かりません。出直してきます・・・
0777nobodyさん04/08/15 17:45ID:???
>>772
if ( $a && $b && $c ){ print "これでよくね?w" }
それとも
if ( $a > 0 ){ if ( $b > 0 ) { if ( $c > 0 ) { print "天山ツームストン" } } }
にするか?いっそのこと
exit || exit;
でいいんじゃん?
0778nobodyさん04/08/15 17:46ID:???
ウホッ!?フィーバーだ!w
0779nobodyさん04/08/15 17:47ID:???
なんだこれ アホらし
0780ぢおぢお04/08/15 18:01ID:YD+WDikb
>777
なりませんでした。
0781nobodyさん04/08/15 18:08ID:???
>>780
バカじゃん
0782ぢおぢお04/08/15 18:10ID:YD+WDikb
何が?
0783nobodyさん04/08/15 18:18ID:???
>>782
こいつマジでバカ
0784nobodyさん04/08/15 18:41ID:???
制御構文で質問です。
foreachのように、毎回スカラにリストの内容を代入する
           +
forのように$iに現在のループ回数を入れる。

みたいなことは不可能ですか?foreach側で使うのは keys %hash なのでforの$iとリンクさせる形での
処理はできません。
078578404/08/15 18:45ID:???
うまく説明できませんでしたが、foreachの途中で現在のループ回数を調べて、
ループ回数が一定の基準を超えると、発動する処理をしたいのです。
0786nobodyさん04/08/15 18:49ID:???
>>785
ダサいやつでいいなら
$i = 0;
foreach(@a){
処理〜;
print "2桁キター" if $i > 9;
$i++;
}
で一応できるよ。
078778404/08/15 19:00ID:???
>>786
さっそくありがとうございます!
0788nobodyさん04/08/15 19:28ID:???
%data = (
a => 1,
b => 2,
c => 3,
d => 4,
e => 5,
);
@a = keys %data;
delete @data{@a[1..3]};

これが
$data = {%data};
の場合に
delete @data->{@a[1..3]};
としてもうまくいきませんが、何か方法はありますか?
0789黒死犬 ◆EgxBlf8nvc 04/08/15 20:17ID:???
delete( @$data{ @a[1..3] } );

こうですね
0790nobodyさん04/08/15 23:12ID:???
readでSTDINから読んで、$bufferに代入したいんですが、いきなりリファレンスとして代入というのはやってもいいんでしょうか?
read(STDIN,$$buffer,$ENV{CONTENT_LENGTH});
のようにすればできたのですが、いきなり$$bufferに代入するとおかしい気がするので(シンボリックリファレンス?なんか非推奨って読んだ気がします)
$buffer = \"";
read(STDIN,$$buffer,$ENV{CONTENT_LENGTH});
とかを考えてみました。
0791nobodyさん04/08/15 23:37ID:???

☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
★                                               ★
☆ 新規質問は名前欄・メール欄を空にして行え                  ☆
★                                               ★
☆ 質問者が返信する際は、名前欄に「最初に質問したレス番号」を入れろ  ☆
★                                               ★
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
0792nobodyさん04/08/16 01:57ID:???
メール欄を空にするとage荒らし死ねと言われる。
0793nobodyさん04/08/16 02:09ID:???
上げっぱなしで続けるからだろ。
こんなところか。

☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
★                                                ★
☆ 新規質問は名前欄・メール欄を空にして行え                   ☆
★                                                ★
☆ 返信は名前欄に「最初に質問したレス番号」・メール欄に「sage」を入れろ ☆
★                                                ★
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
0794nobodyさん04/08/16 02:11ID:???
メール欄を0にするとブラウザで見てる厨房にどうやってIDだけ消すのと聞かれる。
0795nobodyさん04/08/16 02:15ID:???
>>793
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
★                                              .★
☆                                              .☆
★ 右の星もちゃんと整列させてから書き込め                   .★
☆                                             .☆
★                                               ★
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
0796nobodyさん04/08/16 02:22ID:???
>>795
そういうお前が整列させてから書き込め。
0797nobodyさん04/08/16 09:30ID:???
っていうかそんなルールこのスレにはないだろ
ウザい質問者は徹底スルーが基本だって。
0798nobodyさん04/08/16 09:52ID:f4GvLXd6
$sth = $dbh->prepare(
qq{ INSERT tbl_name SET name="$hoge{name}" sex="$hoge{sex}" weight="$hoge{weight}" }
)
%hogeにはフォームから送られてきたクエリが格納されてます。

このようなSQLインジェクションをやる場合にXSS対策として、
foreach( keys %hoge){
$hoge{_} =~ s/"|'//g;
}

としてるのですが、これでXSS対策は万全でしょうか?とりあえず上のSQL文の場合、クォートさえ消しておけば
全部文字列として解釈されるので、おかしなことにはならないと思いますが、もしも穴がありましたら
ご指導願います。
0799nobodyさん04/08/16 09:56ID:???
>>798
わざわざprepareするんだしプレースホルダ使えよ。
080079804/08/16 10:36ID:???
>>799
プレースホルダ???調べてみます。
080179804/08/16 10:49ID:???
$sth = $dbh->prepare(
q{ INSERT tbl_name SET name="?" sex="?" weight="?" }
);
$sth->execute($hoge{name},$hoge{sex},$hoge{weight});

http://www.rfs.jp/sitebuilder/perl/dbi/02.html#プレースホルダとバインド値
ここを見ながらやってみましたが、これであってるのでしょうか?
後から結びつけることで、SQL構文になってしまうようなバインド値の場合にエラーを出して
executeしないんですかね?
080277204/08/16 11:52ID:???
>>777
いや、俺にマジレスされてもさ・・・>>771に聞いたんだから。
0803nobodyさん04/08/16 17:39ID:YMFVNVGs
質問させてください。
telnetにて正常動作したperlスクリプトをCGIとして動かすと
エラーになってしまいます。

ログをたどると以下のようになってます。
Can't locate CGI.pm in @INC (@INC contains:
/usr/home/xxx/usr/local/lib/perl5/5.8.4/i386-freebsd
/usr/home/xxx/usr/local/lib/perl5/5.8.4
/usr/home/xxx/usr/local/lib/perl5/site_perl/5.8.4/i386-freebsd
/usr/home/xxx/usr/local/lib/perl5/site_perl/5.8.4
/usr/home/xxx/usr/local/lib/perl5/site_perl
.) at /usr/local/etc/httpd/htdocs/board/index.cgi line 6.
BEGIN failed--compilation aborted at /usr/local/etc/httpd/htdocs/board/index.cgi line 6.
[Mon Aug 16 10:19:51 2004] [error] [client 138.243.201.4]
Premature end of script headers: /usr/local/etc/httpd/htdocs/board/index.cgi

で、不可解に思って、なんでCGI.pmがないんやろかと@INCのフォルダを
洗いざらい調べてみたら、なんときっちり存在しているのです。

なにか他に思いつく原因ってあるでしょうか?
ちなみにperl5.8.4です。
0804nobodyさん04/08/16 17:48ID:???
>>803
@INC の各パスやファイルのパーミッション
0805nobodyさん04/08/16 17:59ID:???
>>804
パーミッションは755です。ちなみに705にしてもエラーが出て、
上記のログがApacheのエラーログに追加されます。
またpmモジュールは読めさえ出来ればパーミッション関係なかったような。
ちなみにpmモジュールのパーミッションは444でした。

@INCの各パスとはどういうことでしょうか?
CGI.pmは/usr/home/xxx/usr/local/lib/perl5/5.8.4に確かに存在していました。
080680304/08/16 18:01ID:???
>>805
名前とE-mailを入れ間違えた。805=803です。
0807nobodyさん04/08/16 18:29ID:???
/usr/home/xxx/ の中に usr/local/lib/perl5/5.8.4 があるって事?
おかしくない?よくわからんけど。
0808nobodyさん04/08/16 18:33ID:???
>>805
/usr
/usr/home
/usr/home/xxx
/usr/home/xxx/usr
/usr/home/xxx/usr/local
/usr/home/xxx/usr/local/lib
/usr/home/xxx/usr/local/lib/perl5
/usr/home/xxx/usr/local/lib/perl5/5.8.4
これらディレクトリ自体のパーミッションが CGI の実行ユーザに対して
開いているか (読取及び実行権限があるか) ? という事。
0809nobodyさん04/08/16 18:34ID:???
たぶん自分の home に自分で入れたんだろう

一番疑われるのは、既出の通りファイルまたはディレクトリのパーミッションが
apache の実行権限で読めないようになってる、という可能性だが、
それじゃないなら、なんだろうなあ
まさか apache が実行時に chroot されてるとかか?
apache の管理人に相談した方がいいような気もする
0810nobodyさん04/08/16 18:55ID:???
>>803
スレ違い
0811nobodyさん04/08/16 18:58ID:???
「Apache(から呼び出されたPerl)が/usr/home/xxxに入れない」に一票
0812nobodyさん04/08/16 20:25ID:???
MD5暗号化、照合ライブラリってないものでしょうか。
cryptがサーバ対応してなくてMD5使えないもので、
ありましたら使い方等教えていただけますと幸いです。
0813nobodyさん04/08/16 20:57ID:???
>>812
http://search.cpan.org/search?query=MD5&mode=all
0814nobodyさん04/08/16 22:50ID:???
>>805
ていうかなんでおまいはサバカンに問い合わせないんだ?
081580304/08/16 23:04ID:???
>>814
問い合わせてみました、返答ですが
「本サーバは若干特殊でお客様のホームデレクトリが仮想ルートと
なっております。(だからホームの下に元々usrとかetcとかあるわけです)
@INCの値を/usr/home/xxx/usr/local/lib/perl5/5.8.4から
/usr/local/lib/perl5/5.8.4に書き換えれば動作します」
とのこと。@INCがおかしくてlib.pmにもアクセスできないのに
どうやって@INCを書き換えればよいのだろうか…。
0816nobodyさん04/08/16 23:54ID:???
>>815
use の仕組みを理解して lib.pm が何をしているか
読み解けばいいんじゃないか。

でもおじちゃんが君の勉強の機会を奪ってあげよう。
BEGIN { unshift @INC, '/usr/local/lib/perl5/5.8.4' }
0817nobodyさん04/08/17 01:06ID:???
>>816
間違っちゃいないが、それはそれで非効率的だな。
原因の根源から断つ考えは出来んのか?
0818nobodyさん04/08/17 01:17ID:???
まともな鯖に引っ越す。
これだな、うん。
0819nobodyさん04/08/17 01:33ID:???
>>817
突然態度がでかくなったな
082080304/08/17 03:32ID:???
>>816
なるほど、@INCも所詮はただの配列だからスクリプト側で
勝手に追加すれってことですね。すこし効率悪いかなとも
思ってましたけど、いざ使ってみると1箇所追加するだけでも呼び出す
ライブラリ全部に反映されるみたいなので結構いい感じです。

ご教授ありがとうございます。
0821nobodyさん04/08/17 13:03ID:???
if(判断式1){
DispError("ERROR") if (判断式2);
$count++;
}

なんですが、
これは判断式1がtrueの場合DispError(ERROR)が発生するとして、
その後の判断式2はどうかかわるのですか?
0822nobodyさん04/08/17 13:34ID:???
>>821
http://www5a.biglobe.ne.jp/~n_rieko/perl/6.htm#6-7
0823nobodyさん04/08/17 13:54ID:4w98o0dA
Perlでモジュールを使ったオブジェクト指向風プログラミングを
始めたんだけど、文字列の変数展開で、
"$Foo->bar()"
みたいな事出来ないかな?

Rubyだと
"#{Foo.bar}"
という書き方が出来るんだけど。。。
■ このスレッドは過去ログ倉庫に格納されています