Perlコーディング初心者質問スレ Part 39
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/11/27 11:35:03ID:DJwiGeFM【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0133nobodyさん
04/12/03 14:26:46ID:???0135119,132
04/12/03 14:31:31ID:OybfBlRl132のdatasort関数の Usage:
# datasort(区切り文字, 型, 順序, キー, 配列)
#
# 区切り文字 ... splitの第一引数
# 型 ... true: cmp, false: <=>
# 順序 ... 降順 -1, 昇順 +1
# キー ... キーとなるフィールドのインデックス(0から数える)
# 配列 ... ソート対象のデータ
#
ベンチマーク取ってないけど、(テストも余りしてない)
データのsplitが(配列の数)回で済む為、少しは速くなると思う。
013783
04/12/03 15:31:58ID:???!?空になりますかそうですか。。。
>>115
>>my @new = bogosort([[1,1,0], [1,1,4]], @data);
>の後ろ側、[1,1,4]が効かず、前側の[1,1,0]だけが有効になってしまいます。。
古いPerlのsortは、比較関数が0を返した時に元の並び順が保障されないので
そのようになるです。
というわけでPerlをバージョンアップすべし。
0138nobodyさん
04/12/03 15:37:24ID:???file_cacheでキャッシュされるのは、何がキャッシュされるんでしょう?
templateの構造や内部的なtemplateの解析結果とかがキャッシュされるのだろうか?
ページそのものじゃないよね、たぶん。
0139nobodyさん
04/12/03 16:13:56ID:???解析したデータ構造を Storable でシリアライズしてキャッシュしてるんだと思う
0140nobodyさん
04/12/03 16:29:48ID:???ありがとうございます。よく読んだらperldocに書いてありましたね・・・orz
これでおよそ50%パフォーマンス向上ってんだから、結構時間掛かるんですね。
014182
04/12/03 17:47:58ID:???素直に
>●先頭から16個目のデータを1次キー、3つ目のデータを2次キーとしてソートする場合
>@address = sort{(split(/,/,$a))[15] <=> (split(/,/,$b))[15] or (split(/,/,$a))[2] <=> (split(/,/,$b))[2]} @address;
のように繋げて書く(というか人に使わせる)ようにします。。くすん。。。
また何かありましたら質問させてください。
ありがとうございました。
0142nobodyさん
04/12/03 20:25:23ID:???このような文字列があるとして、先頭から連続してる&gt;の数を数える方法ってないでしょうか?
できるだけ簡潔に書きたいのですが・・・。
0143nobodyさん
04/12/03 20:51:56ID:???その例だと4つって数え方でいいのか?
0144nobodyさん
04/12/03 21:11:40ID:???こんなんでどう?
$num = $a =~ s/(?:^|(?<=&gt;))(&gt;)/$1/g;
print $num; # 4
0145nobodyさん
04/12/03 21:12:08ID:???$n= length($n)/4;
0147145
04/12/03 21:24:55ID:???$n= length(($a=~ /^((?:>)+)/)[0])/4;
>>144
それだと、 >の連続が後半に再びあったときに・・・
0148nobodyさん
04/12/03 21:36:09ID:???そうです。先頭から>が幾つ連続してるか、って言い方するべきでした。
>>144-147
ありがとうございます。>>146さんのやり方だとそのまま>を任意の文字列への
置換にも使えそうですね。
0149nobodyさん
04/12/03 21:40:41ID:???0150nobodyさん
04/12/03 22:22:14ID:???0151nobodyさん
04/12/03 23:14:28ID:???0153nobodyさん
04/12/03 23:36:48ID:EsHuFZ1r0154nobodyさん
04/12/04 00:02:39ID:orEKzBU3はじめからutf8でソースを書いてuse utf8するか、
encodingプラグマのFilterオプション使えばいける。
後者の例はたとえば
use encoding 'euc-jp', Filter=>1;
package 日本語;
$変数 = 1;
とはいえ、あまり趣味は良くないね。
0155nobodyさん
04/12/04 00:03:00ID:10+aOFQr<!--#include virtual="****.cgi" -->を使いたい。
0156155
04/12/04 00:04:57ID:10+aOFQr0157153
04/12/04 00:17:56ID:U0vSojEFありがとうございます。utf8ですか。
OSもDBもeucなのでeuc以外では考えていません。ってことは無理なんですね(>_<)
"や'や{などで囲ったり色々してみましたが無理でした。あきらめます。
0158nobodyさん
04/12/04 00:21:06ID:???0160nobodyさん
04/12/04 01:35:43ID:???0161nobodyさん
04/12/04 15:38:15ID:???配列を使うと行数の数だけメモリを確保してしまって無駄遣いしてしまいますよね。行数は不明です。
配列を使って、shift→pushってする場合と、以下のようにする場合ではどちらのほうが効率的でしょうか。
open(W, "> file2.txt");
open(R, "file.txt");
$i = 0;
while(<R>){
next unless ($i++); # 先頭の行は除去
print W $_;
}
close(R);
print W time;
close(W);
unlink("file.txt");
rename("file2.txt", "file.txt");
また、他に効率の良い方法などはありますでしょうか。
よろしくお願いします。
読み書き共用で開くということもできるらしいのですが、どのサイトを拝見しても詳しい内容が載っていません。
実用的だと思うのですがなぜなのでしょうか。
0162nobodyさん
04/12/04 15:54:50ID:???で、rename するので unlink は不要かと。
<R>;
while (read(R, $buf, 10240)){
print W $buf;
}
print W time;
close(W) and rename("file2.txt", "file.txt");
0165nobodyさん
04/12/05 14:39:51ID:hMog6IUx取得したいのですがどうしたらいいのでしょうか
use LWP::Simple;
($content_type, $document_length, $modified_time, $expires, $server) = head "URL";
($sec, $min, $hour, $day, $mon, $year) = localtime($modified_time);
$year += 1900;
$mon = sprintf( "%02d" , $mon+1 );
$day = sprintf( "%02d" , $day );
$hour = sprintf( "%02d" , $hour );
$min = sprintf( "%02d" , $min );
$sec = sprintf( "%02d" , $sec );
print "$year年$mon月$day日$hour時$min分$sec秒 更新
0166nobodyさん
04/12/05 14:50:04ID:eDMBo65dShift_JISで作っていこうと思います。
ダブルクォーテーションの中で一部の日本語(「表示」など)が文字化けする問題について
知りたいのですが、どういう時に文字化けするのかがよく分かりません。
なぜフォームから受け取る時には文字化けしないんですか?
分かりにくかったらすいません・・・。
0167nobodyさん
04/12/05 14:50:45ID:???> LWP::Simple
> head($url)
> Get document headers. Returns the following 5 values if successful:
> ($content_type, $document_length, $modified_time, $expires, $server)
> Returns an empty list if it fails. In scalar context returns TRUE if successful.
0169nobodyさん
04/12/05 15:22:25ID:???0170166
04/12/05 15:49:18ID:???ありがとうございました。
0171nobodyさん
04/12/05 17:40:20ID:???HTMLファイルをShift_JISで書いていれば送られるデータはShift_JISだと期待してもよいのでしょうか。
0172nobodyさん
04/12/05 17:58:50ID:???HEADメソッドでだめならGETメソッドを使ってヘッダから取得。
LWP::Simpleではヘッダ部が取れないから、
LWP::UserAgent使うことになると思う。
>>171
一部のブラウザにはeuc-jp固定で送信するものがあるという話。
0173nobodyさん
04/12/05 19:37:19ID:???全てのサイト/ページが更新時刻を返してくれるわけではない。
特にページがCGIなど動的に生成されていたりすると、
更新時刻という概念自体が無かったりして、Date も Last-Modified も返さないことが良くある。
そういうときは、諦めるしかない。
0174nobodyさん
04/12/05 23:57:35ID:mQuG6gLO0175nobodyさん
04/12/06 06:14:11ID:???0177nobodyさん
04/12/06 10:08:16ID:???ファイルが生成されません。
サーバはRedhat9+Apacheで構成されているようなのですが
環境に依存して生成・書込みが出来ないことがあるのでしょうか。
以下のようなルーチンを使用しています。(パスは合っています。)
use MLDBM qw(DB_File Storable);
sub DbmWrite {
my($data, $filename) = @_;
my(%writehash);
tie %writehash, MLDBM, $ini::path.$filename, O_CREAT|O_RDWR, 0666;
%writehash = (%writehash, %$data);
untie %writehash;
}
0179nobodyさん
04/12/06 12:35:45ID:???# とりあえずお気に入りの一覧ということで
&showdir("C:\/Documents and Settings\/Administrator\/Favorites");
sub showdir {
my($dir) = @_;
opendir(DIR, $dir) || die $!;
my(@files) = readdir(DIR);
closedir(DIR);
foreach (@files){
if($_ ne '.' && $_ ne '..'){
$path = $indir . "/" . $_;
for($i=0; $i<$level; $i++){
print " ";
}
print $_ . ((-d $path) ? "/" : "") . "\n";
if(-d $path){
$level++;
&showdir($path);
}
}
}
$level--;
}
現在はこのように書いているのですが、このように書くとディレクトリやファイルなど関係なく、
名前順でソートされてしまうようです(Win2K SP4 ActivePerl 5.6.1)。
2レスに分けます、
0180nobodyさん
04/12/06 12:36:24ID:???aaa.txt
bbb
bbb.txt
ccc
ccc.txt
ddd.txt
このように表示されてしまいます。
これを、まずはディレクトリとファイルでソートして、
そこからファイル名でソートさせたいと思っているのですが、
ディレクトリかファイルかでソートするにはどのように記述したらいいでしょうか。
上の例で言いますと、
bbb
bbb.txt
ccc
ccc.txt
aaa.txt
ddd.txt
このような表示順序にしたいと思っています。
0183nobodyさん
04/12/06 13:36:20ID:???0184JAPU
04/12/06 13:51:45ID:???>>171
無関係の文字コードで送ってくるブラウザもあるようなので注意。古い例で恐縮ですが,たとえばBSD/386版Mozilla/3.xではJIS固定で送信していました。
INPUTはHTMLの文字コードで送られるが,HIDDENは別のコードで送られるという実装もあるようです。(何となく内部処理が想像つきますが…)
いまどきの主要なブラウザをターゲットにするのであれば,HTMLの文字コードがそのまま利用されるという仮定でも問題無いようです。
(FYI) HTMLでは送信されるエンコードを指定することができるが,現状まともに利用されてはいない模様。
cf. http://www.w3.org/TR/html401/interact/forms.html#h-17.3
0185nobodyさん
04/12/06 13:54:44ID:???例えば:
my %file_or_dir;
@file_or_dir{@files} = map { (-d "$dir/$_")? 0: 1 } @files;
@files = sort { $file_or_dir{$a} <=> $file_or_dir{$b} || $a cmp $b } @files;
0186JAPU
04/12/06 14:10:52ID:???>>132 で既に回答出てたの気づかずに >>82 用のコード書いてしまったよ… 悔しいのでとりあえず貼り付けておきます。(インデントずれるので http://www.japu.org/tmp/ayumoesort.pl にも置きました…) あ,手抜きなので注意して。
#! /usr/bin/perl -w
# This code is public domain; I never assert any rights.
# This code is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
use strict;
use constant COND_DTYPE_STR => 0;
use constant COND_DTYPE_NUM => 1;
use constant COND_ORDER_ASC => 0;
use constant COND_ORDER_DESC => 1;
MAIN: {
my @data = ("foo,bar,2,3,4",
"foo,bar,3,4,5",
"fog,bar,2,2,2",
"fgh,bar,3,4,2",
"foo,bar,4,5,6");
my @ordered = ayumoesort(\@data,
{dtype => COND_DTYPE_NUM,
order => COND_ORDER_ASC,
keyno => 2},
{dtype => COND_DTYPE_STR,
order => COND_ORDER_DESC,
keyno => 0});
print "$_\n" foreach @ordered
}
# つづく
0187JAPU
04/12/06 14:11:27ID:???# This code is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sub ayumoesort
{
my $dref = shift;
my @cond = @_;
my @sgn = map { -($_->{order}*2 - 1) } @cond; # ASC: +1, DESC: -1
# Schwartz Transform; cf. Effective Perl or ask Google
# equivalent to:
# @tmp = map { ... } @$dref;
# @tmp = sort { ... } @tmp;
# @$dref = map { ... } @tmp;
@$dref = (map { $_->[-1] }
sort {
foreach my $i (0..$#cond) {
my $r;
if($cond[$i]{dtype} == COND_DTYPE_STR) {
$r = $sgn[$i]*($a->[$i] cmp $b->[$i]) and return $r;
} elsif($cond[$i]{dtype} == COND_DTYPE_NUM) {
$r = $sgn[$i]*($a->[$i] <=> $b->[$i]) and return $r;
} else {
die;
}
}
}
map { my $x = $_;
[(map { (split /,/, $x)[$cond[$_]{keyno}] } (0..$#cond)),
$_] } @$dref);
}
0188nobodyさん
04/12/06 14:14:23ID:???# コードは試してないけど、
まとめてソート
sort { (-d "$dir/$a" <=> -d "$dir/$b") or ($a cmp $b) } @files
ループをディレクトリとファイルに分ける
grep {-d"$dir/$_"}@files
grep {-f"$dir/$_"}@files
>>183
File::Find はソートしてくれないよ。
0189nobodyさん
04/12/06 16:21:10ID:???>>179-180です。<OPTION>で選択するファイル一覧を作っていました。
@files = sort { (-d "$dir/$b" <=> -d "$dir/$a") or ($a cmp $b) } @files; でやりたいことが出来ました。ありがとうございます。
0190nobodyさん
04/12/06 16:57:38ID:kMJjfrXb0191nobodyさん
04/12/06 16:58:07ID:kMJjfrXb0192nobodyさん
04/12/06 17:03:05ID:adgUx9sVほれ。
http://himatsubu.fc2web.com/22/fir/ かなりシュールな心理テストでオモロイ。
0198nobodyさん
04/12/06 22:54:57ID:???正直スマンカッタ
今は反省している
0199nobodyさん
04/12/06 23:45:58ID:PVGalzLMSocketにより他サーバーから読み込み表示させるのとでは
どの程度サーバー負荷は高まるものなのでしょうか?
0200nobodyさん
04/12/07 00:27:16ID:J98ZOjsq実行して・・という風な方法しかないのでしょうか
一度perlでcgiの短いプログラム(50行ぐらい)を作ったことがあるんですが、
こんな短いのでもバグをとるのにすごく骨を折りました。
0202nobodyさん
04/12/07 00:36:00ID:???二分検索法って知ってるかい?
アルゴリズムってのは、なにもプログラムを組む時にしか使えないものじゃないぞ。
0203nobodyさん
04/12/07 05:39:36ID:???そうか?エラーメッセージを読めばどこが悪いかなんてすぐ分かるが。
まさか500エラーが出なくなるまで闇雲にいじってんじゃないよな?
0204200
04/12/07 15:33:29ID:???文法チェックはブラウザ上でソースを入力するとやってくれる
サイトがあったんで、それを使っていました
(cygwin?がうまくインストールできなかったってのもあります)
コマンドでデバッグをするのと違いはあるんでしょうか
>>202
どんどんせばめていけばいいんですね
>>203
>まさか500エラーが出なくなるまで闇雲にいじってんじゃないよな?
そのとおりです。なんで500エラーがでるのかが分からなくて
どこも修正してないに、何回も実行してみたりして・・
結局原因のひとつはcgiのファイルのパスをフルパスで書いてたのが
いけなかったんだと思います。ほかにもあったけど少し前なんで忘れてしまった。
0206nobodyさん
04/12/07 15:51:19ID:9tRllW3iきれいなコード書いて公開してる人のURL教えてください!
0207nobodyさん
04/12/07 16:09:37ID:???「perl excellent source code」でググった。
ttp://www.perl.com/pub/q/documentation
0208nobodyさん
04/12/07 16:27:59ID:9tRllW3iんーと、コードが載ってませんね。
きれいなコード見て、学びたいので、
そういう感じでお願いします。
0210nobodyさん
04/12/07 17:04:28ID:???0211200
04/12/07 17:38:09ID:???コードはインフォシークの無料HPスペースにアップロードして
実行しています。最終的には動作させることができました。
>Perlいれてローカルで動かせ
意図がわからないのですが、これをするとどんな利点があるんでしょうか?
アップロードして実行するのも慣れてくると短時間でできるので。。。
0213nobodyさん
04/12/07 18:08:01ID:???Perl の吐くエラーメッセージを読める
ひょっとして、Perl が行番号入りでエラーメッセージを吐いてくれる
ということを知らなかったりする?
0214nobodyさん
04/12/07 18:11:19ID:???もし仮に
while (@hoge) {
処理
}
と書こうとして @hoge を $hoge と書き間違い、さらに $hoge に何かしら文字列やら入ってたら
無限ループ作っちゃうでしょう。
それを鯖にUPして実行したら鯖に負荷がかかりっぱなしになる。
鯖が落ちたら君の責任。共有鯖なら鯖会社だけでなく他の鯖利用者にも迷惑がかかる。
ローカルなら君のPCに負担かかる。君だけが被害を受けるが全て君の責任。
どっちがいいよ?
0215nobodyさん
04/12/07 18:29:20ID:Oi1PFFsCフォームから受け取ったメールアドレスが携帯電話のメールアドレスかどうか
を判断したいのですが
$nb = $FORM{mail};
if($nb ne $nb !~ /(.*)\@docomo\.ne\.jp/
and $nb ne $nb !~ /(.*)\@ezweb\.ne\.jp/
and $nb ne $nb !~ /(.*)\@(.*)\.vodafone\.ne\.jp/){
"携帯電話メールアドレスとして処理"
}else{
"携帯電話以外のメールアドレスとして処理"
}
としてみたのですが、どうも上手くいきません。
(何のアドレスを入れても携帯以外のアドレスとして処理されてしまいます。)
何が間違っているかどなたか教えていただけますでしょうか。
よろしくお願いします。
0216215
04/12/07 18:41:14ID:???処理が逆になってました。
(携帯外メルアドでも携帯メルアドでも同じ処理になってしまうので大差ないんですが。)
よろしくお願いします。
0217JAPU
04/12/07 18:44:27ID:???$nb ne $nb !~ /(.*)\@docomo\.ne\.jp/
これを,演算子の優先順位をもとに括ると
$nb ne ($nb !~ /(.*)\@docomo\.ne\.jp/)
ここで,() 内は "" (偽) または "1" (真) を返す。これを $nb と(文字列として)比較しているため,多くの場合はこの式全体として「偽」となる。
これを踏まえて,書き直すと
if($nb =~ /\@docomo\.ne\.jp$/i or $nb =~ /\@ezweb\.ne\.jp$/i or $nb =~ /\@\w+\.vodafone\.ne\.jp$/i) {
# 携帯電話のアドレス
} else {
# NG
}
もしくは,
if($nb =~ /\@(?:docomo\.ne\.jp|ezweb\.ne\.jp|\w+\.vodafone\.ne\.jp)$/i) {
# 携帯電話のアドレス
} else {
# NG
}
入門書は「はじめてのPerl」をおすすめする。
i 修飾子については Perl のマニュアル等で熟知すべし。(「プログラミングPerl」または http://www.perldoc.com/)
0218215
04/12/07 18:56:42ID:???迅速で的確なレスありがとうございました。
希望道理のCGIが実行できました。
入門書や教えていただいたURLにも早速行って勉強します。
本当にありがとうございました。
0219nobodyさん
04/12/07 20:20:42ID:???$nb=~ m!\@(?:docomo|ezweb|vodafone)\.ne\.jp$!i
0220nobodyさん
04/12/07 20:58:48ID:???0221JAPU
04/12/07 21:17:03ID:???「初めてのPerl」が正解。
どうも最近「はじめての」と平仮名で書く習慣が…
# There's more than one way to do it.
0222nobodyさん
04/12/08 04:01:02ID:CFZe8E7O記号ばっかで検索もできない…
0223nobodyさん
04/12/08 07:01:35ID:???@{shift};
ソフトリファレンスと解釈される。
# use warningsで曖昧と指摘される。
@{+shift};
+は変数名に使えないから、@{+shift()}と解釈される。
@{shift()}と等価。
0224nobodyさん
04/12/08 07:14:20ID:???×ソフトリファレンスと解釈される。
○@shiftと解釈される。
0225nobodyさん
04/12/08 10:38:37ID:???@{shift()}または@{shift(@_)}が無難。
0226222
04/12/08 20:32:23ID:???ありがとうございます。
+{ hash_ref } とか {; block } とかと同じような原理だとは思ったんですが、
どうしても探し出せなかったので助かりました。
0227nobodyさん
04/12/08 23:28:15ID:???1: getメソッドで送信されてきた文字列$wordの文字コードを判定して、
utf-8だったらsjisに変換して以後の処理に使いたいです。
2: 使ってるサーバー(arenaのsuite2)がPerl5.6.1です。Perl5.8ならなんとかなりそうだとか、
5.6.1でもjcode.pmが入っていればいけそうだというのはグーグルで発見したんですが、
jcode.plしか入っていないようですhttp://web.arena.ne.jp/suite2/support/manual/hp/script.html#cgi
3: sjis,jis,euc-jpに関しての処理の説明は多く発見できるんですが、jcode.plはutf-8は対応していない?ようです。
本当にちょっとしたことなんですが、jcode.plで色々やってもダメだったです。
jcode.pmをインストールしないと無理でしょうか?
0229nobodyさん
04/12/08 23:38:50ID:???この時点で、まだ何もやってないのに質問してる教えて君ってのが丸出しだな
0230nobodyさん
04/12/09 01:34:56ID:???0231nobodyさん
04/12/09 01:35:08ID:???0232JAPU
04/12/09 03:19:09ID:???Unicode 絡みは XS でかかれていますが,Pure Perl の環境でも動作するよう Jcode::Unicode::NoXS が用意されています。
実際にはユーザが意識することは無く,自動的に Jcode::Unicode or Jcode::Unicode::NoXS が読み込まれるので安心です。
■ このスレッドは過去ログ倉庫に格納されています