-
sub getDateStr(){
($sec, $min, $hour, $mday, $mon,
$year, $wday, $yday, $isdst) = localtime(time);
$year += 1900;
$mon++;
$ret = sprintf("%d_%02d%02d_%02d%02d_%02d",
$year, $mon, $mday, $hour, $min, $sec);
return $ret;
}
-
CGIのデバッグには、
open ERR, ">>err.dat";print ERR "status = $status\n" ;close ERR;
みたいな一行をコピー&ペーストして、エラーファイルを使うと便利。
最近はサブルーチン化してます。
sub err {
open ERR, ">>err.dat";
print ERR join(';',@_)."\n";
close ERR;
chmod 0666, "err.dat";
}
-
ファイルを
@temp = <IN>;
みたく読み込んだとき、各要素($temp[0], $temp[1]...)には改行コード(普通は\n)がぶら下がってるから注意。
-
ハッシュのキーには'を使う癖を付けておくと、printの時に楽。
print OUT "value = $HASH{'name'}"
みたいに。
-
もし$strがnullでないなら...というつもりで
if ($str) {
とすると、$str = "0"の時も弾かれるので注意。はまりました。
-
for文で
for ($i = 1; $i <= 5; $i++ ){
って書いたとき、ループ終了後のiの値は6。(これはCも同じ)
何となくBASICの
for i = 1 to 5
のノリで書くと失敗します。
☆foreach $i(1..5)は終了時に多分$i=5です。
-
配列@listの長さっぽいものとして、という意味で$#listが使えますが、これの値は「長さ - 1」です。だから、@listの全ての要素についてループ、は
for($i = 0; $i <= $#list; $i++){
です。ま、foreach使えば関係ないけど...
-
フォルダ内の各要素について、という処理は
if (opendir(DIR, ~/imgs)) {
@list = readdir(DIR);
foreach(@list){
($_にファイル名が入る)
closedir(DIR);
}
-
普通の時間→UNIXシステム時間 の変換。$monは通常の月から1引いた値なので注意。
(8月→"7")
use Time::Local;
($year,$mon,$mday,$hours,$min,$sec)=split(",");
$time = timelocal($sec, $min, $hours, $mday, $mon - 1, $year);
print "$time\n";
-
掲示板とかのセーブファイルについて、CGIが自動的にdirerctoryを作るようにすると、中のファイルが消せなくなることがある。
だから、ファイル/フォルダを作ったら、chmodしておく...と、使う人には便利。ただ、セキュリティー上はまずそうなので、程々に。
open OUT ">hoge.dat";
chmod 0666 hoge.dat;
-
perlでは一行if文やwhile文は、文の後に書く。Cなら
if(index == 3) printf("Hello\n");
となるのは、
print "Hello\n" if($index == 3);
となる。これを使うと
print while <>;
とかいう怪しい文も書ける。
-
icon/以下のファイルから4つのpngファイルをランダムに選択。
選択したファイル(へのパス)は@imgsに格納
my $dir = 'icon/';
my @files;
if (opendir(DIR, $dir)){
@files = readdir(DIR);
closedir(DIR);
}
my @imgs;
my $j = rand($#files + 1);
foreach $i (0..3){
do{
$_ = $files[($j++) % ($#files + 1)];
} while(! /\.png$/);
$imgs[$i] = $dir . $_;
if(!-e $imgs[$i]){ $imgs[$i] = '';}
}
普通にディレクトリをオープンすると、.と..もリストに含まれるので注意。
-
テキストファイルを決まった行数で分割。
open(IN, $ARGV[0]);
for($fn = 0; ; $fn++){
open(OUT, ">". $ARGV[0] . $fn);
print "wrote file $fn\n";
$count = 0;
while($count++ < 500){
$tmp = ;
if($tmp eq ''){
close IN;
close OUT;
exit(0);
}
print OUT $tmp;
}
close OUT;
}
- 数字の連続、みたいなのは本当に書きやすい。
@A = (1,2..4,8..10);
-
回文判定
print pal($ARGV[1]) . "\n";
sub pal{
$_ = $_[0];
return (2 > length()) ? 'true'
: (m/^(.).*$/ && m/^.(.*)$1$/) ? pal($1)
: 'false';
}
と書いたんだけど、実はCでもたいしたことないし。
int pl(char *s, char *e){
return (2 > e - s) ? 1
: (*s == *e) ? pl(s + 1, e - 1)
: 0;
}
int main(int argc, char *argv[]){
char *cp = argv[1];
if(pl(cp, cp + strlen(cp) - 1)) printf("true\n");
else printf("false\n");
return 0;
}
多くの場合、これでも正しく動作する。
int pl(char *s, char *e){
return (2 > e-s) || ((*s==*e) && pl(s+1, e-1));
}
int main(int argc, char *argv[]){
char *cp = argv[1];
if(pl(cp, cp + strlen(cp) - 1)) printf("true\n");
else printf("false\n");
return 0;
}
-
{}で囲った値を変数に代入すると無名ハッシュへのリファレンスになるが、
()で囲った配列の場合は実体になる。[]で囲むと無名配列へのリファレンスを取得できる。
$a = {0=>2};
@A = (0, 2);
$b = [0, 2];