Perlコーディング初心者質問スレ Part 39
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/11/27 11:35:03ID:DJwiGeFM【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
007571
04/12/01 20:13:12ID:ZtAPmMKLすいません、結果は変わりませんでした。
0076nobodyさん
04/12/01 20:39:49ID:???<!--#include virtual="count.cgi" -->
<!-- と # の間を詰める。のがポイント。
というか、Perlの問題じゃないじゃん。
0077nobodyさん
04/12/01 21:12:33ID:???すでにperldoc読まれたかと思うけど、
一応捕捉しておくと、mod_perlじゃなくてもOk, ただし、shared_cacheオプションを使う場合はIPCが必要.
共有サーバーだとしたら、資源の独占は返ってサーバー全体のパフォーマンスを落しかねないので。
もし使えたとしても、file_cacheに留めておくのが無難だと思う。
0079nobodyさん
04/12/01 23:30:32ID:???0080nobodyさん
04/12/02 01:00:15ID:???0081nobodyさん
04/12/02 05:32:13ID:???0082nobodyさん
04/12/02 12:10:08ID:WEQP3q+X●先頭から16個目のデータをキーにしてソートする場合
@address = sort{(split(/,/,$a))[15] <=> (split(/,/,$b))[15]} @address;
●先頭から16個目のデータを1次キー、3つ目のデータを2次キーとしてソートする場合
@address = sort{(split(/,/,$a))[15] <=> (split(/,/,$b))[15] or (split(/,/,$a))[2] <=> (split(/,/,$b))[2]} @address;
ここで、ソート部をサブルーチン化しろとの上司の命令。以下のように書いてみました。
#&datasort(データの型,並べ順,並べ替え時のキー,配列)
#データの型:数値は1、文字列は2
#並べ順:昇順は1、降順は2
#並べ替え時のキー:先頭は0、3番目なら2、5番目なら4という具合。
@address = &datasort(1,1,15,@address);
#並べ替え部のルーチン
sub datasort{
#$format:数値は1、文字列は2 $order:昇順は1、降順は2 $key:ソート対象のキー、先頭は0、5番目なら4など。
my ($format,$order,$key,@data) = @_;
if($format == 1){
if($order == 1){@data = sort{(split(/,/,$a))[$key] <=> (split(/,/,$b))[$key]} @data;}
elsif($order == 2){@data = sort{(split(/,/,$b))[$key] <=> (split(/,/,$a))[$key]} @data;}
}elsif($format == 2){
if($order == 1){@data = sort{(split(/,/,$a))[$key] cmp (split(/,/,$b))[$key]} @data;}
elsif($order == 2){@data = sort{(split(/,/,$b))[$key] cmp (split(/,/,$a))[$key]} @data;}
}
return @data;
}
で、複数のキーを使ってソートする場合の呼び出し方がわかりません。
@address = &datasort(1,1,15,@address) or &datasort(1,1,2,@address);
だと、当然のことながらorより後ろは動かない。
誰か教えてくださいませ。。
それか、サブルーチンの書き方がおかしい?
0083nobodyさん
04/12/02 13:59:06ID:???試しに書いてみた。
sub csvsort {
my $arrayref = shift;
my @cmps;
while (my($n,$cmp) = splice(@_,0,2)) {
++$n;
$cmp =~ s/(\$[ab])/$1\->[$n]/g;
push @cmps, "($cmp)";
}
my $fcmp = eval("sub {" . join("||", @cmps) . "}");
map $_->[0], sort { &$fcmp } map [$_, split /,/], @$arrayref;
}
# @csvを「要素2を文字列昇順、要素0を数値降順」のオーダーでソート
@sorted = csvsort(\@csv, 2=>'$a cmp $b', 0=>'$b <=> $a');
0085nobodyさん
04/12/02 15:06:46ID:???会員制のサイトを作る場合、
ユーザー個々のデータを保存するのは、
CSV形式、それともユーザーごとにファイルを作成してハッシュ配列で保存、
どちらが妥当でしょうか?
例えばハッシュのイメージとしては、
Id 1
Pass 1234
Name A男
Age 42
Job 会社員
というように考えています。
CSVだと、
1, 1234, A男, 男, 42, 会社員
2, 5678, B子, 女, 30, 営業
・
・
・
(以下リストが続く)
↑こういう形式で良いのでしょうか・・・。
よろしくお願いします。
0086nobodyさん
04/12/02 15:12:42ID:???CGIが動いているサーバーの種類がWin系かその他系かを判定する方法ってありますか?
ファイル名を指定してファイル出力を行なうCGIがあるのですが、
Win系ですと大文字小文字関係なく既に存在するものと同名のファイルは作成できませんが、
Linuxとかですと、大文字小文字が区別されるので、作成可能にしようと思っています。
0087nobodyさん
04/12/02 15:43:37ID:???サーバの返してくるhttpヘッダにあるかもしれないので取得するとか、
cgiで環境変数SERVER_SOFTWAREを調べるとかPATHから想像するとか、
systemとかopenとか使えるんだったらperlのバージョンとかを出力させてみるとか、
サポートに聞くとか
008882
04/12/02 17:39:29ID:???>>83
動きませんでした・・・。
もう少し考えてみます。
本心では「本当にサブモジュール化しないといけないのか?」と思いつつ
上司にも逆らえず。
>>83
間違ってる?
returnを省略しても同じ結果なのはわかるのですが。
>>87
system関数が使えるなら、win系に存在しないコマンド(lsとかcatとか)を
実行させればいいと思うのですが。
system関数は中のコマンドが成功すれば0を返すので
unless(system "ls -l"){
Unix系のサーバーでやりたいこと
}else{
窓系のサーバーでやりたいこと
}
でできないかな。
0089nobodyさん
04/12/02 18:24:52ID:???それだったらOSを識別できるコマンドで一度識別してから作ったほうがいいだろー。
unameとかでもいいし。
いちいちunless云々すんのかい?
まぁあくまでsystemやらopenやら使えるなら。
009083
04/12/02 18:26:51ID:???動かないってのはエラーが出るってこと?
それとも正しくソートされないってこと?
一応、動作確認(ActivePerl5.8.4)済みなんだけど・・・
よければ動かない〜の詳細をレス頼んます。
0092nobodyさん
04/12/02 20:54:21ID:???datasortを使う方向で考えてみました。
速度は遅いしメモリ食うしー。
sub bogosort
{
use sort stable;
my ($key, @data) = @_;
foreach(reverse(@{$key})){
my ($format, $order, $key) = @{$_};
@data = datasort($format, $order, $key, @data);
}
return @data;
}
my @new = bogosort([[1,1,0], [1,1,4]], @data);
要素0の数値昇順、要素4の数値昇順でソート。
$keyは[(1:数値/2:文字列),(1:昇順/2:降順),要素]の配列のリファレンス。
0093nobodyさん
04/12/02 21:57:32ID:???初めの頃にケン○やらレス○やらばっか参考にしてたが、
あんなソース見てたらダメだな。
0094nobodyさん
04/12/02 22:01:06ID:???0095nobodyさん
04/12/02 22:06:47ID:???超人業でもなく、ダサダサでもなく、丁度いい感じのソースとおもふ。
0096nobodyさん
04/12/02 22:16:47ID:???いきなり Wiki 設置しようとか思わないだろう
0097nobodyさん
04/12/02 22:24:41ID:???0098nobodyさん
04/12/02 22:39:28ID:???0099nobodyさん
04/12/02 23:04:37ID:???んじゃなかろうかという気がするが、もしあったら漏れにも教えて
0100nobodyさん
04/12/02 23:16:40ID:???インラインでHTMLだーっと書いて、途中から条件分岐で何か処理して、
続きのHTMLをまただーっと・・・ってなる。
0101nobodyさん
04/12/02 23:25:32ID:???HTML::template使うとヘッダ、フッタ、フォーム、メッセージ表示部分、って感じに
分けることはできないから、同じようなテンプレートをいくつか用意する事になるし。
0102nobodyさん
04/12/02 23:58:35ID:???それはそれとして、昔 DBI (Pgsql) + Template Toolkit で掲示板作ったが、
コードのほとんどは入力チェック・サニタイズのための if やら s/// やらの羅列で、
あまりコーディングの勉強に使って欲しくない出来に仕上がってしまった経験がある。
0103nobodyさん
04/12/02 23:59:56ID:???my @str = qw(うんこだ 素敵 ばかみたいだ 楽だ);
print <<"EOM";
ヒアドキュメントに埋め込みができるなんて、
Perlは@{[ $str[int(rand(@str))] ]}よね。
EOM
0105nobodyさん
04/12/03 00:27:48ID:DFUzRW8vperlでブログは作成できますか?
また、何処かに参考サイト、
ソースのおいてあるサイト等があったらご教授ください。
0107nobodyさん
04/12/03 00:40:12ID:???0108nobodyさん
04/12/03 00:44:17ID:???0109nobodyさん
04/12/03 02:26:08ID:???もう全く別物。作り直したほうが早かったなこれじゃ。
0110nobodyさん
04/12/03 03:04:29ID:???Class::DBIと、Data::FormValidatorあたり使えば、
コーディングなんてほとんどしないで掲示板作れるよ。
コーディングの参考にはならんけどね。。
011182
04/12/03 06:16:55ID:???それもそうだな・・・スマソ
>>90
配列が空になります。
実際はここでソートしたものをファイルに書き出す処理があるのですが、0バイト。
CobaltにPerl5.005の組み合わせです。
これがよくないのかな。
あ、エラーは出ません。
>>92
ありがとうございます。
会社でやってみます。
0112nobodyさん
04/12/03 09:03:42ID:dEjygVC1会員制のサイトを作る場合、
ユーザー個々のデータを保存するのは、
CSV形式、それともユーザーごとにファイルを作成してハッシュ配列で保存、
どちらが妥当でしょうか?
例えばハッシュのイメージとしては、
Id 1
Pass 1234
Name A男
Age 42
Job 会社員
というように考えています。
CSVだと、
1, 1234, A男, 男, 42, 会社員
2, 5678, B子, 女, 30, 営業
・
・
・
(以下リストが続く)
↑こういう形式で良いのでしょうか・・・。
よろしくお願いします。
0113nobodyさん
04/12/03 09:16:50ID:???設計考えてどうすか?ってのは
△▲ WebProg 初心者の質問 Part11 ▼▽
ttp://pc5.2ch.net/test/read.cgi/php/1101635909/
こっちが妥当だと思うが。
011482
04/12/03 10:50:46ID:???ダメでした。。
use sortでInternalServerError。
サーバーアナライザーで見ると、sortと書かれたモジュールが見つからないのですが
それが原因かな・・・。
もうちっと考えて見ます。
011582
04/12/03 11:23:05ID:???>>92
use sort〜の行を外すと動くのですが、
>my @new = bogosort([[1,1,0], [1,1,4]], @data);
の後ろ側、[1,1,4]が効かず、前側の[1,1,0]だけが有効になってしまいます。。
上司に「サブルーチン化せず、1行にまとめてorで繋げたほうが素直」って
言ってはいるのですが・・・
「無理です」って言ってやろうかと思う今日この頃。
ありがとうございました。
0116nobodyさん
04/12/03 11:49:21ID:???@list = qw(3 5 8 4 2 9 6 1 7);
#この例だと9が保存されている位置の5が欲しい
foreachで回しながら比較していくしかないのでしょうか?
0117nobodyさん
04/12/03 11:53:46ID:25445hqZソートして先頭か末尾取り出せば?
とスレの流れを見て言ってみる
0118nobodyさん
04/12/03 11:54:48ID:25445hqZごめん。よく読んでなかった。orz
0119nobodyさん
04/12/03 11:56:11ID:???use sortはプラグマ、おそらく perl のバージョンが古いと使えないはず。perl5.6以降だったかな。
>>82 のコードは、条件が多くなるとsliptの回数がすごい事になりそうなので、
これをキャッシュする様な仕組みを考えるといいと思う。参考までに、CPANより
http://search.cpan.org/~jnh/Sort-Fields-0.90/Fields.pm
0120nobodyさん
04/12/03 12:17:33ID:???ファイルを開いたりせずに強制的にダウンロードダイアログを表示させる事は可能でしょうか。
例えば、<A href="hoge.txt">hoge</A>などのリンクがあって、これをIEで踏むとIEがファイルを開いてしまいます。
これをダウンロードダイアログを出したいと思っています。
現在使っているサーバー(@nifty)ではCGI設置ディレクトリにあるログファイルなどへの直接のアクセスはできないので、
CGIを通してダウンロードを行ないたいと考えています。
多分出力するContent-typeの周辺をいじればいいのではと考えているんですが、
参考になるようなサイトをご存知の方はいらっしゃらないでしょうか。
0121nobodyさん
04/12/03 12:23:42ID:???119が紹介したモジュール使った方が便利だと思うが
テキトーに書いてみた。
sub datasort {
my($spec, @list) = @_;
return sort {
my $r = eval {
my @a = split(/,/, $a);
my @b = split(/,/, $b);
foreach (@$spec) {
my($format, $order, $index) = @$_;
my $r = ($format == 1)? (@a[$index] <=> @b[$index]):
($format == 2)? (@a[$index] cmp @b[$index]):
die "型が変: @$_";
next if $r == 0;
return ($order == 1)? $r:
($order == 2)? (-$r):
die "並べ順が変: @$_";
}
return 0;
};
if ($@) { die "$@" }
return $r;
} @list;
}
0122nobodyさん
04/12/03 12:24:07ID:???http://www.google.com/
0123nobodyさん
04/12/03 12:28:49ID:???content-typeをapplication/octet-streamにしてやればたいてい
ダウンロードにいくとは思うが、ブラウザの類の挙動の話なので
perlとは関係ないからスレ違い。
0124nobodyさん
04/12/03 12:35:07ID:???List::Utilのreduce使って
reduce { $list[$a]>$list[$b]? $a: $b } 0..$#list
0125nobodyさん
04/12/03 13:54:20ID:???例えば<OPTION>で、0 時として送信したときに偽として処理されてしまいます。
0126nobodyさん
04/12/03 13:56:51ID:???if($input_data != ""){
}
0127nobodyさん
04/12/03 13:57:35ID:???0128nobodyさん
04/12/03 13:57:48ID:???if($input_data ne ""){
}
0129125
04/12/03 14:00:11ID:???ありがとうございました
0130nobodyさん
04/12/03 14:03:50ID:???昔は参考になるスレだったのに残念です
0131nobodyさん
04/12/03 14:18:51ID:???めでたいことじゃないか。
0132nobodyさん
04/12/03 14:26:10ID:OybfBlRlsub datasort($$$$\@) {
my ($separator, $types, $orders, $keys, $data) = @_;
die "ERROR: datasort()の引数が間違っています。\n"
unless ($#types == $#orders and $#orders == $#keys);
my $keys_len = scalar @$keys;
my $data_len = scalar @$data;
my %data_index = map {
$_ => [(split($separator, $data->[$_]))[@$keys]]
} (0..$data_len-1);
my @sorted_index = sort {
my $ret;
for (0..$keys_len-1) {
my $n = $data_index{$a}[$_];
my $m = $data_index{$b}[$_];
my $type = $types->[$_];
my $order = $orders->[$_];
($ret = $order * ($type?($n cmp $m):($n <=> $m))) ? last : next ;
}
$ret;
} (0..$data_len-1);
return map {$data->[$_]} @sorted_index;
}
my @data = ("1,2,3,4,5", "0,0,0,0,5", "0,9,7,6,0", "1,3,5,7,9", "2,4,5,7,0");
for (datasort(qr/,/, [1,1], [-1, 1], [4,2], @data)) { print "$_\n"; }
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:mQuG6gLO■ このスレッドは過去ログ倉庫に格納されています