Perlコーディング初心者質問スレ Part 44
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2005/10/17(月) 00:47:17ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0233nobodyさん
2005/10/25(火) 10:21:14ID:???会員認証ごとの認証をおこなった後にその認証情報に基づいたページを作る場合、クッキーを利用する方法と、都度HIDDENで情報をひっぱる方法のどちらが良いのでしょうか?
ちなみに、携帯でもアクセスする可能性が大なサイトを作ろうと思っています。
やっぱりHIDDENの方が無難なのでしょうか?
0235nobodyさん
2005/10/25(火) 12:12:56ID:???課題は自分でやれ。
ここ自助努力をサポートする場所であって、お前の家庭教師じゃないよ。
>>233
携帯は Cookie 使えん機種が多いので NG。セッション管理を Web アプリ側で
行なって、セッション ID を Cookie ではなく type="hidden" で引っ張るのが吉。
0236nobodyさん
2005/10/25(火) 15:43:33ID:???というCGIを作ろうとして、下記のようなものを作ってみました。
#!/usr/bin/perl -w
use CGI;
use CGI::Carp qw(fatalsToBrowser);
my ($form, $ht, $datafile, $data_line, $dir);
$dir = './test';
$form = new CGI;
print "Content-Type: text/plain; charset = shift_jis\n\n";
$ht = $form->param('ht');
$datafile = $dir."/".$ht."html";
open(FH, $datafile);
@list = <FH>;
foreach $data_line( @list ) {
print $data_line;
}
close (FH);
これを実行してhtmlを表示しようとしたのですが、うまく表示されません。
できましたら修正のヒントを教えてもらえますでしょうか?
0238nobodyさん
2005/10/25(火) 15:56:07ID:???せっかく fatalsToBrowser 使ってるんだから、せめて
openのエラーはチェックしろよ。
open(FH, $datafile) or die "cannot open $datafile: $!";
ぐらいでいいからさ。
0239236
2005/10/25(火) 16:16:12ID:???openのエラーチェックしたら、見事にミスってました。
$datafile = $dir."/".$ht."html";
のところで拡張子のピリオド付け忘れてました_| ̄|○
修正したら無事表示されました。
ありがとうございました。
0240nobodyさん
2005/10/25(火) 18:33:41ID:???http://www.ipa.go.jp/security/awareness/vendor/programming/a04_01.html
0241nobodyさん
2005/10/25(火) 20:18:09ID:acj/FLSv実際にプログラム test.pl を実行している様子です。
なぜ、ファイル data の最後の行が表示されてしまうのでしょうか。
最後の行の末尾には改行文字がないので、最後の行(内容は一文字のゼロ)を $line に読み込んだ直後に、
while を抜けるはずだと予測したのですが。
%cat test.pl
#! /usr/local/bin/perl
while ($line = <>) {
print $line;
}
%hexdump -C data
00000000 33 0a 32 0a 31 0a 30 |3.2.1.0|
00000007
%./test.pl < data
3
2
1
0
# 最後の行に改行文字を持たないファイルは、truncate コマンドを使って作成しました。
0242nobodyさん
2005/10/25(火) 20:43:30ID:???perldoc perlop を見るとわかると思うけど、
while ($line = <>) { } は while (defined($line = <>)) { } と等価なので。
0243nobodyさん
2005/10/26(水) 03:47:32ID:WCtFX3bD一度アップした画像を、最大記事件数を超えた時点で削除する
プログラムを書いていたのですが、どうしてもうまくいきません。
一個一個の記事に、画像のアドレスが$file_nameとして入っていて、
if($file_name ne ''){ push (@img_dels , "./img/$file_name"); }
で、最大記事件数を超えた分の記事に付いている画像のアドレスを配列に入れて、
unlink @img_dels;
としても、きちんと画像が削除されません。
if(-e )を使って調べてみると、
./img/$file_nameでは、存在しないことになっており、
一方、./img/2005001.jpgというように、具体的な値をプログラム内に入れれば
問題なく削除できるのです。
つまり、変数$file_nameを使っているとうまく作動せず、
その変数の部分を、何か具体的なファイル名を入れてみると、
きちんと動作するのです。
なので、パーミッションの問題ではないかと思うのですが、
他にどういった点が怪しいのでしょうか?
以上、よろしくお願いいたします。
0244殿ツー
NGNGどなたかお力添えくださればうれしいとです
まずなにをインストールすればいいとですか??
0246nobodyさん
2005/10/26(水) 07:33:22ID:???0247nobodyさん
2005/10/26(水) 10:42:10ID:???>>7
http://www.site-cooler.com/kwl/perl/environment.htm
0249nobodyさん
2005/10/26(水) 14:39:04ID:???1<>あああ<>
2<>いいい<>
3<>ううう<>
@testに上記データの読込
$hikakuに比較する変数
$bbb_newは$aaaが合致した場合に入れる
foreach (@test) {
($aaa,$bbb) = split(/<>/);
if ($hikaku eq $aaa){
push(@test_new,"$aaa,$bbb_new");
} else {
push(@test_new,"$aaa,$bbb");
}
}
全上書きで@test_newをデータ書き込み
こんな感じで、要はデータ修正用のものを組んでみたのですがなぜかこれを走らせる都度先頭に半角スペースが入ってしまいます。
1<>あああ<>
2<>いいい<>
3<>ううう<>
なぜなんでしょうか?
0251nobodyさん
2005/10/26(水) 15:03:54ID:???走らせるって@test_newをprintするとってことか?
そもそも
push(@test_new,"$aaa,$bbb_new");
は
push(@test_new,"$aaa<>$bbb_new");
にしたいんじゃないかと
0252249
2005/10/26(水) 15:11:27ID:???>>251
すいません。カキコ時ミスでした。
そうです。
push(@test_new,"$aaa<>$bbb_new<>\n");
です。
保存時は
&Memory2($dataname,"@test_new");
…とし、保存時流用のため、サブに飛ばしています。
そのサブは以下のようにしています。
sub Memory2 {
local ($param) = @_[0];
local (@param2) = @_[1];
open(OUT, "> $param");
print(OUT @param2);
close(OUT);
chmod(0666,$param);
}
0253nobodyさん
2005/10/26(水) 15:13:11ID:???0254nobodyさん
2005/10/26(水) 15:28:49ID:???> &Memory2($dataname,"@test_new");
~~~~~~~~~~~~~
しっかり括ってるじゃないか・・・原因はこれ
ダブルクォーテーションで括った場合の配列変数の展開は以下と同等
join(@array, $")
$"のデフォルト値は半角スペースだからこういうことになる。
&Memory2($dataname,@test_new);
とすればよい
0255254
2005/10/26(水) 15:30:08ID:???join($", @array)
が正解
0256249
2005/10/26(水) 16:01:49ID:???&Memory2($dataname,@test_new);
…とすると1行目の変数しか書き込まなかったので、ダブルクォーテーションを付けていました。
サブに飛ばさず、
open(OUT, "> $dataname");
print(OUT @test_new);
close(OUT);
…とすれば、半角スペース問題が解決しました。
本当にありがとうございました!!
0257nobodyさん
2005/10/26(水) 16:12:14ID:???ああ、スマソサブルーチンのほうをよく読んでなかった。こっちも間違ってるな
local ($param) = shift @_;
local (@param2) = @_;
とか
local ($param) = @_[0];
local (@param2) = @_[1..$#_];
とかにしないと。
でも、いまさらlocalは古いと思うが・・・
Perl4にも対応しなくてはならないということでなければmyを使うのがお勧め
my $param = shift;
my @param2 = @_;
0259nobodyさん
2005/10/26(水) 18:29:58ID:???0260nobodyさん
2005/10/27(木) 18:26:04ID:MmBYG7yb@flagの中に一つでも1があったら
1を返したいのですがよい方法があったら教えていただけないでしょうか?
今の所
if(@flag == 1 && $flag[0] == 1){
return 1;
}elsif(@flag == 2 && $flag[0] == 1&& $flag[1] == 1){
return 1;
}elsif(@flag == 3 && $flag[0] == 1&& $flag[1] == 1&& $flag[2] == 1){
return 1;
}elsif(@flag == 4 && $flag[0] == 1&& $flag[1] == 1&& $flag[2] == 1&& $flag[3] == 1){
return 1;
}elsif(@flag == 5 && $flag[0] == 1&& $flag[1] == 1&& $flag[2] == 1&& $flag[3] == 1&& $flag[4] == 1){
return 1;
}else{
return 0;
}
とやっているのですが不恰好なので。
0261260
2005/10/27(木) 18:29:10ID:MmBYG7yb>@flagの中に一つでも1があったら
じゃなくて@flagの中全部1だったらです。
0262nobodyさん
2005/10/27(木) 18:44:52ID:???http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq4.html#How_can_I_tell_whether_an_list_o
sub check {
$_ == 1 || return 0 for @_;
1;
}
print check(@flag) ? 'OK' : 'NG';
0263nobodyさん
2005/10/27(木) 19:43:10ID:???0265nobodyさん
2005/10/28(金) 01:41:57ID:bf2gwUIh/(^0^)/;
/(f^_^)/;
}
0266nobodyさん
2005/10/28(金) 01:54:14ID:???0267nobodyさん
2005/10/28(金) 06:37:45ID:OMxdiAJ2foreach (@flag){
if($_ == 1){ return 1; }
}
じゃ駄目?
>>257
my($param, @param2) = @_;
ってやっちゃ駄目ですか?
自分のスクリプトではこうやって渡しちゃってるんですが・・・
0268nobodyさん
2005/10/28(金) 06:48:30ID:zLDMG+JKsub flagcheck{
my(@flag) = @_;
foreach (@flag){ if(!$_){ return 0; }}
return 1;
}
0269nobodyさん
2005/10/28(金) 06:49:19ID:zLDMG+JKforeach (@_){ if(!$_){ return 0; }}
return 1;
}
これでよかったか
0270nobodyさん
2005/10/28(金) 07:01:39ID:???if(!$_){ return 0;
より
return 0 unless $_;
の方が……どうでもいいか。
それより、0と1しか入っていないことは保障されてる?
0271nobodyさん
2005/10/28(金) 07:11:26ID:zLDMG+JK書きながらそれは思ったけど、質問の段階で 0 と 1 しか出てこなかったので ^^;
1 以外が入ってれば … も考えるなら
if($_ != 1){ return $_; }
かな?
0272nobodyさん
2005/10/28(金) 07:20:20ID:???次の行に return $_;
個人的にだけど、否定だけで分岐する場合にはunlessが見やすいと思う。
0273nobodyさん
2005/10/28(金) 07:33:02ID:FKANG7gPrequireしたファイルの中でグローバルを宣言するにはどうしたらいいのでしょうか?
requireしたソース中でmy宣言したらその中でしか見えず、エラーが出てしまいました
0274nobodyさん
2005/10/28(金) 07:52:12ID:???kentのように、1つの変数をずっと使うような設計は止めたほうがいい。
>requireしたソース中でmy宣言したらその中でしか見えず、エラーが出てしまいました
ソースのmyというか、スコープをもう一度勉強して。
むりやりstrictでエラーを出させないようにするなら、qw($hoge);
0275nobodyさん
2005/10/28(金) 09:05:27ID:???274の言うように可能なら変数を見せなくてすむように設計を見直した方が
いい場合が多いが、どうしてもやりたいのならモジュールにしてimport/export
するのがいいんじゃないかね。
0276nobodyさん
2005/10/28(金) 09:15:21ID:FKANG7gPrequireした先でのグローバル確保したいってのは止めた方がいいというのは分かってはいるのですが・・・
やっぱ面倒くさがりはじめるとエラーが多くなるんでしょうかね。
出来る限り引数、戻り値を設定して呼ぶようソース見直します。
ありがとうございました。
0277nobodyさん
2005/10/28(金) 09:23:34ID:???コーディングはファイルサイズ増えても、半角スペースとタブをうまく使うようにするといいよ。
あと、コメントも適度にあるといいね。
0278nobodyさん
2005/10/28(金) 10:43:47ID:???参照/設定専用のサブルーチンを作ってそれでアクセスするようにすればいい。
オブジェクト指向で言うところのアクセサってやつ。
0279nobodyさん
2005/10/28(金) 10:59:28ID:???といったカッコをつけたコードはどういう意味があるのでしょうか?
0280nobodyさん
2005/10/28(金) 11:10:09ID:???リスト。
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perldata.html#List_value_constructors
0281nobodyさん
2005/10/28(金) 11:14:37ID:???myをまとめて指定する場合()でくくる必要がある。
別にmy @flag = @_;でも可
my ($hoge,@flag) = @_; としていて、$hogeを消した名残かもしれない。
my (@flag) = @_;
my ($foo, $bar);
my (@age, @sage); と連続して書く場合、見た目の為?に括弧くくりしてあるのも見かける。
0282nobodyさん
2005/10/28(金) 11:26:27ID:3fcMXuGTってする時に括弧をつけるので、見た目統一のために1つのみの宣言でも括弧を付けてます。
0283279
2005/10/28(金) 12:31:13ID:???右辺のコンテキストを変えた、もしくはmyの適用範囲を指定したコーディングでもないのに
カッコを付けるのが紛らわしく感じたのです。
0284nobodyさん
2005/10/28(金) 13:18:53ID:???> my($param, @param2) = @_;
> ってやっちゃ駄目ですか?
もちろん構わない
shiftを使って引数を取り出すかリストコンテキストで一気に代入するかは好みが現れる所だろうな
しかし、自分でも書いた後、説明とはいえ
> local ($param) = @_[0];
> local (@param2) = @_[1..$#_];
こんな回りくどいやり方は無いなと思った…しかも上間違えてるし$_[0]
0285nobodyさん
2005/10/28(金) 13:36:59ID:???それ激しく同感。上手くタブとスペースを使い分けて書かれてるソースってめったに見られないよな
よくあるのがこういうインデントだけど、タブ幅が変わると悲惨なことになる
if (expression) {
____for (range) {
[_TAB__]{ #Some blocks
[_TAB__]____function(multiline,
[_TAB__][_TAB__]_____arguments)
[_TAB__]}
____}
}
漏れの思う理想形はこんな感じ。これならタブ幅がいくら変わっても適切なインデントで見られる
if (expression) {
[TAB]for (range) {
[TAB][TAB]{ #Some blocks
[TAB][TAB][TAB]function(multiline,
[TAB][TAB][TAB]_________arguments)
[TAB][TAB]}
[TAB]}
}
0286nobodyさん
2005/10/28(金) 15:23:43ID:???上の例、ひどすぎないか?
tab size を 8 にして、indent size を 4 にしているということ?
> よくあるのがこういうインデントだけど、
よくあるのか・・・?
0287nobodyさん
2005/10/28(金) 15:30:15ID:???そういうこと
Perlの標準モジュールとか見てみれ 大半がこんなだよつд`)
CGI.pmとかMemoize.pmとか
0288nobodyさん
2005/10/28(金) 15:36:36ID:???同じソースを複数人で弄っていて、コーディング規約も何もない場合
tab と space が混在してもっとひどいことに・・・。
0289nobodyさん
2005/10/28(金) 15:58:45ID:???Emacs のデフォルトがそんなんだったような。
漏れの思う理想形は、タブは一切使わず SPACE のみでインデント。
Emacs なら (setq-default indent-tabs-mode nil) しると。
0290nobodyさん
2005/10/28(金) 16:52:13ID:???スペースのみか、それも良いな
でも、漏れが読むときは全部タブに置換することが度々
スペースで固定しちゃうと、その人の好みのインデント幅に合わせて
読めないというのがあるんだよなぁ…
# 個人的に、使い慣れてるエディタ上でのタブを表す→を、
# インデントとしてみるように目が慣れちゃってるのもあるのかも
まあ好みは人それぞれ分かれるから、他人のソースを読むときは
PerlTidyを通すのを習慣付けろってことか、これは
0291nobodyさん
2005/10/28(金) 17:03:56ID:???0293nobodyさん
2005/10/28(金) 17:43:28ID:???何かの間違いじゃ・・・
ttp://search.cpan.org/src/LDS/CGI.pm-3.11/CGI.pm
こことか。133行目付近
unless ($OS) {
unless ($OS = $^O) {
require Config;
$OS = $Config::Config{'osname'};
}
}
0294nobodyさん
2005/10/30(日) 20:33:55ID:???ファイルハンドルを局所化することは可能でしょうか。
再帰したサブルーチンの中で毎回違うファイルを扱いたいのです。
0295nobodyさん
2005/10/30(日) 20:49:09ID:???ファイルハンドルへのリファレンスだか型グロブだか(よく理解していない)を
局所化した変数に入れておけば解決できるのではと思いつきました。
その方向で調べてみますが、方向性が間違っていましたら教えてください。
0296nobodyさん
2005/10/30(日) 20:51:31ID:???引数にファイルを指定するぐらいかな?
0297nobodyさん
2005/10/30(日) 21:05:36ID:???オープン、処理、クローズの、処理の部分でもう一度再帰的に自分自身を呼び出しているので、
クローズする前に同じハンドルで別ファイルをオープンしてしまってるんです。
0298nobodyさん
2005/10/30(日) 21:14:33ID:???http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq5.html#How_can_I_make_a_filehandle_loca
0299nobodyさん
2005/10/30(日) 21:59:42ID:???ありがとうございます!!そのままずばりの質問でしかもFAQということで
まことに恐縮です。おかげさまで解決しました。
0301nobodyさん
2005/10/30(日) 23:02:00ID:ZWocYOMF意味を教えて、と言うものです。ごめんなさい。
既存のソースを使って勉強中に、フォームをデコードしたい部分で
read(*******略*******);
undef(%in);
というものが出てきました。
undef とはどういう関数なのでしょうか。
リファレンスで探してみたのですが、名前付き単項演算子として列記されているだけで、
解説が載っていませんでした(初心者向けだから?)
ぐぐってみたものの、他の項目の解説用のソースばかり出てきてしまい、
undef の解説が見つけられず、困っています。よろしくお願いします。
0302nobodyさん
2005/10/30(日) 23:06:21ID:???どういう調べ方してんだ。
0303nobodyさん
2005/10/30(日) 23:09:40ID:ZWocYOMFで検索してみたのですが…
何か手がかりがあれば教えていただきたいのですが。お願いします。
0304nobodyさん
2005/10/30(日) 23:11:28ID:???まあまあ
>>301
Perlの組み込み関数は
perldoc -f 関数名
でマニュアルが見られる。ただし英語だけど。
日本語訳は
http://perldoc.jp/docs/perl/5.6.1/perlfunc.pod
http://www.att.or.jp/perl/man/perlfunc.1.html
このへん
で、undefがどういうものかというと、その変数の値を未定義にする関数。
まあ、その例ならば%inを空にすると考えてもらっても良いと思うよ
0306nobodyさん
2005/10/30(日) 23:20:17ID:ZWocYOMF(つづりまちがいは、ここに書いたときだけでした;)
ソースに undef(%in); と出てくるものの、 %in は後にも先にもここ一つなのですが…、
どこにも出てこない変数をクリアすることに意味はあるんでしょうか?
(もしかして、悪いモノを見本にしてしまったのでしょうか)
(呼び出しているプログラムは jcode.plのみです)
0308nobodyさん
2005/10/30(日) 23:46:23ID:???%inじゃなくて$in{...}の形ででてきてるかもね。
しかし%inをundefして使いまわそうとしている
あたりあまり筋がよさそうではないので、手本に
はしないほうがいいんじゃないかなー。
0309nobodyさん
2005/10/30(日) 23:48:12ID:???> (もしかして、悪いモノを見本にしてしまったのでしょうか)
模範的といえるような綺麗なPerlスクリプトって正直なかなか無いからねぇ。
現状良い見本を見て育った人のほうが少ない気もする
0310nobodyさん
2005/10/30(日) 23:51:26ID:???0312301
2005/10/31(月) 00:25:50ID:8r5lDkYL載っていないことが多かったのですが、
教えていただいたリファレンスとかも読んで、わかってきました。
これまでに、COBOLしかやったことがなかったので、
勘違いしていることもありました(汗
ありがとうございました。
0313nobodyさん
2005/10/31(月) 00:27:31ID:???0314nobodyさん
2005/10/31(月) 00:33:54ID:???0315nobodyさん
2005/10/31(月) 00:37:35ID:???phpとかrubyでは良くみるけどperlで使えたっけ?
0316301
2005/10/31(月) 00:50:00ID:8r5lDkYLcgi-lib.plは使ってないんです。
コボラーとしては、宣言もなしに変数がイキナリ使われていることに慣れません…
0317nobodyさん
2005/10/31(月) 00:58:02ID:???use strict;してないのはそんなのばっかりですよ。
大手よりも細々とやってるとこの方が、意外としっかりしたコードかいてることが多いです。
kentのはジンマシン出るかもしれないので注意してください。
0318nobodyさん
2005/10/31(月) 01:00:04ID:???英語アレルギーじゃないならCPANにあるソースでも読んでみると良いかもよ
http://www.cpan.org/scripts/index.html
0319301
2005/10/31(月) 01:17:17ID:???てか、[安全ではないコンストラクトを制限]と言われても
具体的にピンと来ないのですが・・・
自分で全部ソース書くよりも、
便利なモジュール使ったほうが間違いがない…ってことですかね。
Kent-webのCGIは、そのまま(改造とかナシで)使ったことがあります。
見た感じでは、ダラダラ〜っと大きいルーチンが書いてあって
読みづらいと思ったのですが(だからあんまり見てない)
見本にするには不向きってことですか?<ジンマシン
0320nobodyさん
2005/10/31(月) 01:40:06ID:???use strictは一言で言えば安全にプログラミングするためのプラグマだが…
とりあえず、一番のご利益は宣言の強制かな
my宣言をせずにいきなり変数を使おうとすると
エラーにするなどの機能を有効にする。というようなのがuse strict 'vars';
my $hoge = 'hogehoge';
print $hage; # use strict;すれば$hageは宣言されて無いのでエラー
見たいなミスを予防したりできる。
Kentは・・・まあ見本にはお勧めしないとだけ言っておこうか
0321nobodyさん
2005/10/31(月) 02:43:49ID:???いい見本は、コアモジュールのコードを読めばいいと思う。あと高いけど駱駝本
0322nobodyさん
2005/10/31(月) 02:55:53ID:???0324名無し募集中。。。
2005/10/31(月) 03:15:06ID:s3JdPwyc0325301
2005/10/31(月) 03:24:24ID:???ありがとうございます。
VBで言うところの、Option Explicit みたいな役割ってことでしょうか。
またまた質問なんですが、グローバル変数の宣言は、
$hensu;
だけでOKなんですか?
my とか local に相当する言葉はナシで良いのでしょうか。
(my と localについての解説しか見当たらないので)
検索していて our というのも見つかりましたが…
0326nobodyさん
2005/10/31(月) 03:42:25ID:???見るんじゃない、感じるんだ。
>>325
文法を 1 から 10 まで習うつもりか?
入門書か、perlsyn と strict.pm の perldoc ぐらい読んでから来いよ。
0327321
2005/10/31(月) 10:23:36ID:???ま、ああいう言いにくいことは、自分のblogで書けないからね
ここでなら言っちゃってもいいかなーって思ってぶっちゃけたw
0328nobodyさん
2005/10/31(月) 14:02:09ID:???0329nobodyさん
2005/10/31(月) 16:26:16ID:mS98tkDz<div id="aaa">から</div>までの間には、<div id="bbb">〜</div>とか<div id="cc">〜</div>とかがいっぱい入ってるんですが。。。
0330nobodyさん
2005/10/31(月) 17:16:04ID:???開きが見つかれば+1
閉じが見つかれば-1
0の時点で閉じがあれば、そこで終了。
0331ヽ(´ー`)ノ ◆.ogCuANUcE
2005/10/31(月) 17:17:06ID:???use warnings;
use HTML::TreeBuilder;
my $doc = HTML::TreeBuilder->new_from_file('test.html');
map { $_->delete() } $doc->look_down('_tag' => 'div', 'id' => 'aaa');
print $doc->as_HTML();
こんでいいかね。
■ このスレッドは過去ログ倉庫に格納されています