Perl の基本 2
「Perlの練習 その2 家計簿 PerlKakeibo」 で実際に使った関数などです。
flock とは
flockの引数2は排他ロック、1は共有ロック、8はロック解除
eval{flock(LOGFILE,2);};
evalによって、flock関数がある場合にだけ実行することができる。
ファイルを1行ずつ読み込み配列に格納
@DATA = <LOGFILE>;
i行目のデータは
$DATA[i-1]
で取り出すことが出来る。@DATA は行入力演算子と呼ばれる。
@DATA で要素数を表せる。
while でループ実行する
while (条件式){
print文などの実行;
++$i とかで条件を追加;
}
加算演算子
例えば合計を計算したい。$aaa $aaa_all
$aaa_all = $aaa_all + $aaa;
これを略して書くと、
$aaa_all += $aaa;
ヒアドキュメント
ヒアドキュメントはhtmlの出力に非常に便利。
qqなども同じ用途で使われるが、どうして必要なんだろ?
qq では
print qq(HTML文1);
print qq(HTML文2);
print qq(HTML文3);
だが、ヒアドキュメントを使うと
print <<END;
HTML文1
HTML文2
HTML文3
END
END と END の間に何行でもHTMLで記載できるので簡単で便利。
例えば、
print <<END;
<FORM METHOD="POST" ACTION="write.cgi" NAME="form">
END
のように使う。
open関数のモード
open < FILE名 | 開いたファイルからデータを読み込む。 |
open > FILE名 | 開いたファイルにデータを出力する。元ファイルは破棄。ファイルが無い場合は新規作成。 |
open >> FILE名 | 開いたファイルにデータを追加する。ファイルが無い場合は新規作成。 |
数字の整形表示
$current_yymm = sprintf("%04d\%02d",$year,$mon);
$current_yymm = sprintf("%02d\%02d",$year,$mon);
yearが4桁なのに間違って%02d としてしまいましたが、2桁切り捨てられることなく4桁表示されました。
keys 関数 とは
ハッシュ %aaa に key1 key2 key3 という3つのキーがあるとすると
keys %aaa
は
('key1','key2','key3')
というリストを返します。
foreach とは
foreach $x ('AAA','BBB','CCC') {
print "$x "
}
を実行すると
AAA BBB CCC
と出力されます。 カッコの中のリストの値を$x に代入して、リストの数だけprintを実行します。この場合は要素の個数が3つなので、3回printします。
foreach これは使えそうです。
データを1行ずつ読み込んで、ソートする
ハッシュとkeys関数、sort関数を使えば実現できます。
ハッシュはキーとデータの2つの要素を持っているので、キーにソートしたい値を入れればソートできます。
foreach $key (sort keys ハッシュ) {}
キーを指定して、ハッシュ%aaaの値を取り出すには
$aaa{キー}
です。
$aaa(キー)
ではありません。
最初エラーが出る理由がわからず、{ } が ( ) になっているのに気がつくまで1時間以上かかりました。
こういうミスが多いです。
文字の切り出し関数 substr()
$aaa = substr(文字列,何番目から,半角何文字切り出す);
$aaa = substr("ABCDEFG",1,3)
とすると、 $aaa は BCD となります。 (1番目のBから3文字)
このsubstrも今後かなりの頻度で使うことが予想されます。
年月日から曜日を計算
2011/03/03 のようなスラッシュ入り形式の年月日から曜日を導き出す必要がありましたので、いろいろ調べて、一番短くてすみそうな以下の形にしました。
(timelocal関数 や localtime関数 については「Perl 時刻の処理はとりあえずこれで」)
$youbi_y = substr($mmdd,0,4);
$youbi_m = substr($mmdd,5,2);
$youbi_d = substr($mmdd,8,2);
$date_wday = (localtime(timelocal(0, 0, 0, $youbi_d, $youbi_m - 1, $youbi_y - 1900)))[6];
@wdays = ("日","月","火","水","木","金","土");
$youbi = $wdays[$date_wday] ;
4行目をtimelocalに渡す年の表示を間違えて、最初は
$date_wday = (localtime(timelocal(0, 0, 0, $youbi_d, $youbi_m - 1, $youbi_y)))[6];
としていましたが、結果は同じでした。1900引かなくてよいんでしょうか?あれこれ試しましたが、1900を引いても引かなくても同じ曜日が出力されているようでした。
なんだか気になりますが、ここでこだわっていては肝心の家計簿が動くようになりません。
とりあえず正しい結果が出ているので今回はあまりこだわらないことにします。後で時間があったら戻って確かめます。
入力チェック
文字数のチェック length 関数
量指定子 {}
{m} m 回の繰り返し
{m,} m 回以上の繰り返し
{m,n} m 回以上、n 回以下 -->数字の桁数チェックに使える
変数$aaaと正規表現にマッチするか否かを調べます。
if ($aaa =~ /[0-9]+/) # 正規表現にマッチすれば
if ($aaa !~ /[0-9]+/) # 正規表現にマッチしなければ
$aaa が6桁までの半角数字以外の場合エラーを出します。 値無しでも可。
if($aaa !~ /^\d{0,6}$/){&error;}
$mmdd が4桁か8桁の半角数字以外の場合。
if($mmdd !~ /^(\d{4}|\d{8})$/){}
参考: とほほ
for 文
j が1から9になるまで、何かを9回実行します。
for ( $j=1; $j<=9; $j++)
{
なにかを実行;
}
エラー処理と die関数
CGIモジュール
基本中の基本モジュールだそうです。
use CGI;
とすれば使えます。
なぜ必要かというと、HTMLの出力が簡単になります。
あとフォームから入力されたデータを取り込めます。
参考:
PerlプログラミングTips 簡潔。わかりやすい。
ファイルが存在するかどうか:テスト演算子
-e ファイルが存在するか?
-z ファイルサイズがゼロか?
if (-e ファイル名){ }
if (-z ファイル名){ }
ファイルオープンの可否による処理
if (!open(ファイルポイント,"> ファイル名")) { open出来なかった場合の処理 }
else { openできた場合の処理 }
ファイルの削除とファイル名の変更
ファイルを削除
unlink ファイル名
ファイル名を変更
rename "変更前ファイル名", "変更後ファイル名"
四捨五入
少し実用的なプログラムを作りたくて、株関連の簡易DBのようなものをperlを使って作ろうとしている。
お金が絡んでくると、どうしても必要なのが四捨五入。
use Math::Round;
というのを使えば簡単らしいので、それを読み込んだが、エラーが出て使えなかった。サーバーが対応してないのかも。
http://d.hatena.ne.jp/perlcodesample/20081001/1222963156
のようにsprintf を使えばよいらしいが勉強のため、自分で関数を作ってみることにした。
汎用は難しいので、小数点以下一桁のみの四捨五入関数を作った。
配当利回りなどの利回り系の値が小数点以下10桁以上の値をとっているのだが、確認表示する場合はそんなに必要ない。%化して四捨五入して小数点以下1桁にして返してやろうというもの。
# 100倍して%化。四捨五入して小数点1桁にすする
sub round01 {
my $in = @_[0] ; # 四捨五入する数
my $back = int(($in * 100 + 0.05) *10 ) / 10; # 四捨五入後の数
return $back ;
}
**********************
- Perlの基本 その2
- Perlの練習 その2 家計簿 PerlKakeibo メモ
- Perl 時刻の処理はとりあえずこれで
- Internal Server Error でCGIプログラムが動作しない 2008/08
- Perl のエラー解決と疑問点整理 2008/08
- Perlの練習 その1 電気料金の簡易計算フォーム
- Perl の基本