くだすれPerl(超初心者用)3
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2009/03/31(火) 22:20:27ID:???もしくは質問者自身何が何だが分からない質問を勇気を持って書き込むスレッドです。
Perl使いが優しくコメントを返しますが、
お礼はPerlの布教と初心者の救済をお願いします。
前スレ
くだすれPerl(超初心者用)2
http://pc11.2ch.net/test/read.cgi/php/1204488452/
関連スレ
Perlについての質問箱 39箱目
http://pc12.2ch.net/test/read.cgi/tech/1234181856/
Perlコーディング初心者質問スレ Part 59
http://pc11.2ch.net/test/read.cgi/php/1234752149/
【Perl上級者コーナーPart01】
http://pc11.2ch.net/test/read.cgi/php/1024741312/
0110nobodyさん
2009/06/08(月) 13:47:40ID:???0111nobodyさん
2009/06/10(水) 22:04:38ID:???ものぐさなぼくは
> /<(.*?)>/
を支持する。
/<([^>])>/ よりもタイプ数が少ない。
区切り文字が変更されたときに修正する文字数が一文字少ない。
0112nobodyさん
2009/06/10(水) 23:01:32ID:???0113nobodyさん
2009/06/17(水) 13:26:38ID:???内部でtime関数を読んでるんですが、外からこれを制御することは可能でしょうか
不可能の場合はどうテストすべきでしょうか
0114nobodyさん
2009/06/17(水) 14:08:32ID:???0117nobodyさん
2009/06/17(水) 14:37:45ID:???テスト用のスクリプトからこのモジュールを呼んでちゃんと動くかどうか確認したかったんですが、
モジュール内部でtime関数を使って計算する部分があるためにきちんと統制できないので、
テストスクリプト側に返ってくる値が予測できないのです
なので、time関数が返す値をテストスクリプト側から操作したいのです
0118nobodyさん
2009/06/17(水) 14:56:26ID:???./command.pl 1010101010
みたいにコマンド実行時にUNIX秒渡せば簡単だと思うけどどういうスクリプト&テスト方法なのかわからん
0119nobodyさん
2009/06/17(水) 15:31:12ID:???そうですね、一つのテストスクリプトでテストしたいのでそれではちょっと面倒な気がします
実際にどういうことをやろうとしてるのか見てもらったほうが早いかもしれませんね
実際はもっと長いですが、モジュールとスクリプトを簡略化したのはこんな感じです
関数・変数のネーミングが微妙なのは無視して下さい
----- Util.pm -----
package Util.pm
# 何日後かを形式に則って出力
sub makeTimeString {
my $date_diff = shift;
my $now = time();
my @time = localtime($now + $date_diff * 60 * 60 * 24);
my $date = sprintf "%4d/%2d/%2d %2d:%2d:%2d", ($time[5] + 1900, $time[4] + 1, $time[3], $time[2], $time[1], $time[0]);
return $date;
}
1
----- test.pl -----
use Util.pm;
use Test::Simple tests => 1;
#今日の場合
ok makeTimeString(3) eq "2009/06/20 3:28";
0120nobodyさん
2009/06/17(水) 17:22:21ID:???組み込み関数の挙動が正しいかどうかを確認したいの?
まず$now + $date_diff * 60 * 60 * 24の値が0〜2147483647までの数値かどうかチェックさえすれば
あとは組み込み関数の挙動だからなぁ。。。
0121nobodyさん
2009/06/17(水) 17:52:21ID:???いつでも何度でもモジュールがちゃんと思った通りに動くかどうか、間違いがないかどうか確認したいんですよ
これからちょっと関数内部を変更したとしてもこのテストスクリプトを動かすだけで正しい動作かどうかチェックできるようにしたいです
ここではtime関数から返ってくる値が起動ごとに違うのでうまくチェックできないじゃないですか
なのでtime関数から渡される数値を同じになるようにテストスクリプト側で操作したいんです
0122nobodyさん
2009/06/17(水) 18:52:14ID:???0124nobodyさん
2009/06/17(水) 19:28:00ID:???そこで思考停止しちゃうのか・・・なんだかなぁ。
俺だったらmodule内で拾ったepoc値を外部コマンドに投げて比較すればいいかなーとか思ってるけど。
秒単位の精度はいらなそうに見えるし。
0125nobodyさん
2009/06/17(水) 19:42:53ID:???それも考えましたが、結局同じロジックにしても違うロジックにしても、自動で結果を出すことになるので信頼できないと思いまして
それに処理をしてるうちにtime関数で返ってくる値が変わる可能性がありませんか?
0126nobodyさん
2009/06/17(水) 20:33:48ID:???my $now = ($test)? 0 : time();
でいいじゃん。
0127nobodyさん
2009/06/17(水) 20:43:30ID:???組み込み関数自体の信頼性は疑ってないです
ただ、スクリプト側でtimeを呼んだときとモジュール側でtimeを呼んだとき、
処理の時間があるのでどうしてもズレがあるわけじゃないですか
それからモジュール側から返ってきた値をチェックしたいので、
チェックするにはスクリプト側でtimeの値を計算してやらなきゃいけない
ということはスクリプト側の計算ロジックも正しい必要があると思います
でも直感的に6月17日の3日後の日時と比較するのなら正しいかどうかが一目でわかると思いまして
0128nobodyさん
2009/06/17(水) 20:46:54ID:???呼び出し元でtime関数使ってるならそのepoc値渡せばいいだけじゃん。
テストも簡単だぜ?
0129nobodyさん
2009/06/17(水) 20:54:41ID:???それなら確かにズレはなくなりそうですが…
テストの為に関数に風穴開けるのはなんかスマートじゃない気がします
それからテスト側でロジック組む必要がある問題は解決して無くないでしょうか?
0130nobodyさん
2009/06/17(水) 21:03:18ID:???あんた言ってることがめちゃくちゃだ。
0131nobodyさん
2009/06/17(水) 21:08:05ID:???「6月17日の3日後の日時と比較する」のは「テスト側のロジック」に見えるのだが。
というか>>128で言ってるのは
・普段は外から「timeから取得したepoc値」渡す。
・テスト時は「固定値」を渡す。
って意味だよ?
風穴とかスマートとかいう個人的な感性は知らんけど、timeの返り値を外から固定ってのがスマートとはとても思えない。
0132nobodyさん
2009/06/18(木) 05:49:48ID:sDQdBVF1すみません、勘違いしてました
そうですね、関数の引数を増やせばテストは簡単そうですが…
>>131
できる限り引数を減らしたいんです
モジュール側から見たときに、現在時刻を用いてゴニョゴニョするなら
timeを渡さないほうがすっきりしてると思いませんか?
テストをする場面でスマートであるよりも、実際に使われるモジュール・関数単位でスマートであるべきだと考えてます
これは今回の場面だけでないと思います
例えばDBIのラッパーモジュールを作って、
携帯からの記事投稿とPCからの投稿で異なるデフォルト値を設定したいとします(記事タイトルとか)
このとき、タイムスタンプに常に現在時刻を押すとすると、
記事に関する色んなステータスに加えて時刻までもが引数として渡されることになりますが、
それはモジュールとして完結してるのかという話です
確かにテストのために引数を増やせば楽ができますが、もしテスト側でtimeの値を操作することができるなら、
無駄を出さなくて済みますよね
0133nobodyさん
2009/06/18(木) 06:35:23ID:???>記事に関する色んなステータスに加えて時刻までもが引数として渡されることになりますが、
>それはモジュールとして完結してるのかという話です
それを「完結してない」と思う理由が俺には全くわからない。
「引数以上に無駄を出さず、time関数の返り血を制御する」方法は無いと思うが、
どうもこれ以上やりとりしても信条を曲げるつもりが無い以上ずっと平行線だろう。
ま、がんばってくれ。
0134nobodyさん
2009/06/18(木) 06:51:03ID:???考えすぎてかえって遠回りしちゃうタイプw
0135nobodyさん
2009/06/18(木) 07:10:19ID:???ちなみにこの問題の解決策はあるよ
関数の引数減らすのも普通の考え方じゃねぇの?
0136nobodyさん
2009/06/18(木) 07:37:30ID:???俺も知りたいw
0138nobodyさん
2009/06/18(木) 10:41:06ID:???0140nobodyさん
2009/06/18(木) 11:21:32ID:???0141nobodyさん
2009/06/18(木) 11:23:53ID:???次の質問をどうぞ!
0142nobodyさん
2009/06/18(木) 18:11:54ID:???オーバーライド
----- test.pl -----
#! /usr/bin/perl
use strict;
use warnings;
use lib './lib';
use Time::Local;
use Test::More tests => 1;
use_ok 'Util';
my $time;
{
package Util;
use subs 'time';
sub time{
# 2009/06/17 03:28:00
return $time;
}
}
# 2009/6/17 03:28:00
$time = timelocal 0, 28, 3, 17, 6 - 1, 2009;
ok Util::makeTimeString(3) eq "2009/06/20 03:28:00", "t_value: ". Util::makeTimeString(3);
# 2009/5/30 01:15:13
$time = timelocal 13, 15, 1, 30, 5 - 1, 2009;
ok Util::makeTimeString(5) eq "2009/06/04 01:15:13", "t_value: ". Util::makeTimeString(5);
0143nobodyさん
2009/06/18(木) 18:14:39ID:???package Util;
sub makeTimeString {
my $date_diff = shift;
my $now = time();
my @time = localtime($now + $date_diff * 60 * 60 * 24);
my $date = sprintf "%04d/%02d/%02d %02d:%02d:%02d", ($time[5] + 1900, $time[4] + 1, $time[3], $time[2], $time[1], $time[0]);
return $date;
}
1
ちなみに Test::MockTime Time::Fake といったそれ用のモジュールもあります
ごめん答え知ってて聞いてた
0144nobodyさん
2009/06/18(木) 20:51:05ID:???1.割り切って日本限定
2.DateTimeを使う
3.Unix限定と割り切ってPOSIXのtzset使う
0145nobodyさん
2009/06/18(木) 21:21:59ID:???0147144
2009/06/18(木) 21:29:00ID:???0148nobodyさん
2009/06/18(木) 21:41:58ID:???0149nobodyさん
2009/06/18(木) 21:45:11ID:???なんかすまんです
そんでタイムゾーンをどう使ってテストする場合の話ですか?
>>146
本当に聞きたかったのは他人がどういうテストしてるのかなんですよね
この答えであってるのか、もっといい方法があるんじゃないかと
0150nobodyさん
2009/06/18(木) 21:49:47ID:???答えは十分出たと思うけどね。
どの方法が「良い」かなんて自分にしか決められないしキリがない。
そういう意味ではお前さんの聞き方は卑怯だったよ。あとスレタイ良く読めw
0151144
2009/06/18(木) 22:19:00ID:???ええと、localtime使うと時差が出るじゃないですか。
テストする場所で結果が変わると思うので、
その対処方法を聞きたかったのです。
0152nobodyさん
2009/06/18(木) 22:31:44ID:???0153nobodyさん
2009/06/18(木) 22:59:24ID:???Windowsの場合、上手く動かないんです。
use POSIX qw(tzset tzname strftime);
$ENV{TZ} = 'GMT+0';
tzset;
my ($std, $dst) = tzname;
print "$std $dst\n";
print strftime('%Y-%m-%d %H:%M:%S', localtime), "\n";
-- Linux(Debian)
GMT GMT
2009-06-18 13:48:27
-- WindowsXP
東京 (標準時) 東京 (標準時)
2009-06-18 22:46:20
# やっぱりgmtimeに置き換え?
0154nobodyさん
2009/06/18(木) 23:10:33ID:???それってwindowsではgmtが取得できて無いってだけで、localtimeの動作としては合ってるんじゃないのか?
0155nobodyさん
2009/06/19(金) 01:05:31ID:???Cでも書いてみたのですが、それはLinuxと同じ動作をしました。
結局、下のようなテストケースでUnix:OK, WIndows:NGなのでどうしましょうということでした。
use Test::More qw(no_plan);
use POSIX qw(tzset);
$ENV{TZ} = 'GMT+0GMT';
tzset;
my $now = localtime(1245338340);
ok($now eq 'Thu Jun 18 16:19:00 2009', $now . ' localtime test');
0156nobodyさん
2009/06/19(金) 14:25:45ID:ceoCS57Hダウンロード数をカウントするために、PHPアップローダーからアップロードしたファイルを収納しているディレクトリを
CGIのダウンロードカウンターのほうで読み込んで、アップローダーからファイルにアクセス→リダイレクトして
ダウンロードカウンタのURLに移動してファイルを表示、という事をしているのですが、
ダウンロードカウンタの設定で、画像にアクセスしてもブラウザで開かず、ファイルのダウンロードが開いてしまいます。
何時間もググって調べたのですが、プログラムを全くやった事がないので、結局解決しませんでした。
どうすれば、画像をブラウザで開くように出来るんでしょうか。
http://localhost/uploda/src/nico61.txt
これが使ってるカウンタのスクリプトです。
詳しい方、どこを弄ればいいのか教えて頂けないでしょうか。
宜しくお願いします。
0157nobodyさん
2009/06/19(金) 14:30:52ID:???0158nobodyさん
2009/06/19(金) 14:39:19ID:ceoCS57Hごめんなさい間違えました。
0159nobodyさん
2009/06/19(金) 14:42:27ID:ceoCS57H度々すいませんこれです。
0160nobodyさん
2009/06/19(金) 14:55:44ID:ceoCS57Hこれです、ほんとすいません。
0161nobodyさん
2009/06/19(金) 15:09:27ID:???127.0.0.1 niconama.ddo.jp
と書いておけばいいぞ。
0162nobodyさん
2009/06/19(金) 22:11:17ID:???スーレーちーがーいー
【 スクリプト改造依頼スレ】(丸投げ) part7再々
http://pc11.2ch.net/test/read.cgi/php/1222645553/
0164nobodyさん
2009/06/20(土) 11:40:20ID:???以下のように書くと、「真」が表示されます。
if ("真" eq "真" ){
print "真";
}
しかし、以下のように書くと、「真」は表示されません。
if ("真" =~ /真/ ){
print "真";
}
if ("真" =~ "真" ){
print "真";
}
if ("真" =~ /"真"/ ){
print "真";
}
=~ を使用する場合において、「真」が表示される
ようにするにはどうしたらよろしいのでしょうか。
基本的なことですが、どうしても分からないので
質問させていただきました。よろしくお願い致します。
0165nobodyさん
2009/06/20(土) 12:06:50ID:???CP932でコードを書くのをやめるという選択肢もあります。
0166164
2009/06/20(土) 13:33:31ID:???検索サイトでいろいろなキーワードで検索していたのですが、
なかなか答えとなるものが見つかりませんでした。
回答は非常に助かりました。ありがとうございます。
0168nobodyさん
2009/06/22(月) 03:35:03ID:mckf9gfOCGIの勉強をしていてCGIの製作を行っているのですが、レスポンスが遅い気がします。
abでベンチを書けてみたのですが、10リクエストの処理に5秒もかかっています。(そんなに重いCGIではないです。
自分のコードの書き方が悪いのか、それともマシンが遅いのか調べたいのですが、abをかけるいいサンプルのようなものは無いでしょうか。
他のマシンでどれくらいのスピードで動いているかなどのサンプルがあるものだとうれしいです。
0169nobodyさん
2009/06/22(月) 04:00:45ID:???Devel::Profiler
Devel::NYTProf
これで性能分析ができるらしい
ボトルネックあるならこれで分かるだろー
0170nobodyさん
2009/06/28(日) 17:18:33ID:I7LpaOR5Jcode.pmに文字コードを自動認識させようとするとたまに誤変換するんだが
(たとえば「えー」をucs2に変換させようとすると「?????」に化ける)
その辺の認識精度を上げるにはどうすればいいのかな?
WebページはUTF-8で構成しているけど、フォーム入力から飛んでくる
文字コードはブラウザが勝手に決めてしまう、って認識で合ってるよね?
0171nobodyさん
2009/06/28(日) 18:06:04ID:???0172nobodyさん
2009/06/28(日) 19:37:43ID:???ページのそれと変えたい場合もしくは、より厳密にしたい場合のために、HTML4ではform属性にaccept-charsetが追加された。ただしIE6は未対応。
このレスはたぶん大体あってる。
0173nobodyさん
2009/06/28(日) 22:09:18ID:???ブラウザの仕様はどうであれ、どんなコードでも対応できるように作っておくのはとても大切。
hiddenで文字コード判定用の文字列をpostしておくと良い。
0174nobodyさん
2009/06/29(月) 01:22:45ID:???0175nobodyさん
2009/07/05(日) 01:58:48ID:???恐らく GET のパラメータの文字コードが utf-8 でないためだと考えています。
どのようにすれば解決できるでしょうか。
#!/usr/bin/perl
use CGI;
my $cgi = CGI->new();
my $str = $cgi->param("str");
print $cgi->header( -charset => 'UTF-8' );
#1
print $str;
#2
sub {map {print $_, "\n"} split(//,shift) }->($str);
0176nobodyさん
2009/07/05(日) 02:10:22ID:???そうじゃぁなければ use Encode しれ
0178nobodyさん
2009/07/26(日) 00:42:20ID:J3wl39Kv今日もネタもないのにageてやるからな!
 ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
∧_∧ ∧_∧ age
(・∀・∩)(∩・∀・) age
(つ 丿 ( ⊂) age
( ヽノ ヽ/ ) age
し(_) (_)J
0179nobodyさん
2009/07/29(水) 22:19:43ID:???CGI(Perl)を使って外部のサイトからHTMLソースを取り込むにはどうしたら良いでしょう?
外部サイトのデータから統計を取って、データとして出力するようなCGIが書高と思ってます。
0181nobodyさん
2009/07/29(水) 22:25:45ID:???0182nobodyさん
2009/07/29(水) 22:46:06ID:???知らないなら、「わかりません」って言えよ
0185179
2009/07/30(木) 01:23:24ID:???ありがとうございます。
0186nobodyさん
2009/08/04(火) 17:31:46ID:opJYW1lj文字化けする文字をこのように変えたいのですが変換されません。
どのように書けばいいのでしょうか。
$a =~ s//高/g;
よろしくお願いします。
0187nobodyさん
2009/08/04(火) 18:22:15ID:???0188nobodyさん
2009/08/04(火) 18:46:13ID:Udgymmfyが文字化けするので高に変えたいってこと?
0189nobodyさん
2009/08/05(水) 08:42:09ID:57ai1vyR0190nobodyさん
2009/08/05(水) 10:00:37ID:2mkcb2/Uありがとうございます。
>>188
はい、そのようにしたいと考えております。
187さんのおっしゃる通りに、書いてるコードを確認したところEUCでしたので
sjisに変えてみたところ、うまくできました!
ここ数日、悩んでいたのですっきりしました。
187さん、188さん、ありがとうございました。
0191nobodyさん
2009/08/05(水) 20:48:29ID:???任意の文字で囲まれた
文字列をすべて抽出する方法がわかりません。
たとえば、abcabcabcといった文字列に対し
aとcで囲まれたすべての文字列を取得するには
どうすればいいのでしょうか?
この例だと
abc
abcabc
abcabcabc
abcabc
abc
が該当します。これらをすべて抽出したいのですが。
0192nobodyさん
2009/08/05(水) 21:27:00ID:???while($str =~ m/(a)/g){
my $pos = pos($str);
my $result = $1;
while($str =~ m/([^c]*c)/g){
$result .= $1;
print "$result\n";
}
pos($str) = $pos;
}
0193191
2009/08/06(木) 09:27:03ID:???>>192さん ありがとうございました。
思っていたように動作しました。
続けての質問で申し訳ないのですが
アルファベットで構成されるランダムな文字列
CFGTARFEQZCAZVHNNNGZYAKLOPYL..(みたいな感じです)
から例えば、Aから始まり X,Y,Zを中に含まず XまたはYまたはZで終わる
文字列をすべて抽出するには
どのようにすればよいのでしょうか?
実際には単一のアルファベットの連続ではなく
ONETWOTHREEFOURFIVE..のように
単語が適当に連続しているものと想定して使用できる記述を
(ONEで始まりSIXを含まずTENで終わり のように)
提案していただけると助かります。
よろしくお願いします。
0194191
2009/08/06(木) 09:38:23ID:???単語はONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TENが想定される
のように、あらかじめ分かっていて指定することができます。
0195nobodyさん
2009/08/06(木) 15:43:26ID:0zj+bmfk0196nobodyさん
2009/08/06(木) 23:46:37ID:???sub start {
my ($item, $sub) = @_;
return sub{
my ($str) = @_;
my $start = 0;
while((my $new = index($str, $item, $start)) >= 0){
$start = $new+length($item);
$sub->(\$str, $start, length($str), $item);
}
};
}
sub without {
my ($item, $sub) = @_;
return sub{
my ($str, $start, $end, $result) = @_;
my $new = index(${$str}, $item, $start);
$end = $new if ($new >= 0 && $new < $end);
$sub->($str, $start, $end, $result);
};
}
0197nobodyさん
2009/08/06(木) 23:47:37ID:???my ($item) = @_;
return sub{
my ($str, $start, $end, $result) = @_;
while(1){
my $new = index(${$str}, $item, $start);
($new >= 0 && $new < $end) or last;
$result .= substr(${$str}, $start, $new+length($item)-$start);
$start = $new+length($item);
print "$result\n";
}
};
}
my $str = join('', map{
qw(ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN)[int(rand(10))]
} (1..100));
print "$str\n\n";
start('ONE', without('SIX', end('TEN')))->($str);
0198191
2009/08/07(金) 00:23:46ID:???動作検証し、勉強させていただきます。
複数のファイルから質問のようなことをしたくて
テキストエディタでの単純な正規表現での処理だと面倒なので
やったこともないプログラミングのようなことをを試みたのですが
単純なマッチングでは、オーバラップしているところが
検索から漏れて困ってました。
0199196
2009/08/07(金) 01:07:13ID:???終わりの条件を複数にするのを忘れてたけど、
$subを配列にしてループさせると、探索条件を複数にすることもできると思う。
0200nobodyさん
2009/08/07(金) 01:34:42ID:???是非わが社に(笑)
掲示板見てると出来る人そこそこいるのにperl経験者募集かけても全然こないのは
年寄りが多いのか…若くてもそこそこの地位になってるのか…
正規表現あんまり自信ないですくらいなら許せるが
リファレンスもOOPもわかりませんって人多くて最近疲れ気味だ(泣)
0202nobodyさん
2009/08/07(金) 10:28:18ID:wZBhH2760203nobodyさん
2009/08/08(土) 08:08:10ID:nShQ5pki$b = "str$astr";だと最初の「str」で途切れるし
$b = "str$a str";にすると空白はいっちゃうし
0204nobodyさん
2009/08/08(土) 08:38:19ID:???"str$a\str"
0205nobodyさん
2009/08/08(土) 09:58:31ID:???0206nobodyさん
2009/08/10(月) 13:15:14ID:LPa3QqaE0207nobodyさん
2009/08/13(木) 09:14:17ID:NeVAVZeH受け取ったデータまんま返したいんです
環境変数を使い分けるの面倒だし
■ このスレッドは過去ログ倉庫に格納されています