Perlコーディング

ディレクトリ削除

2008年01月17日
Perlでディレクトリを削除する方法です。

$result = rmdir("ディレクトリのパス");
if($result == 0){
 $err_msg = "ディレクトリを削除できませんでした。";
}

Perlコーディング

ネットビジネスを支援する新ツール完成

2007年12月25日
こつこつ作っていた、新ツールが完成しました。とある方から共同運営のお話しがあり、私がコーディングを担当していました。それが完成しました。


今までにない新しい発想のツールです。今はまだ詳しくは書けませんが、リリース前には再度書き込みます。1月中旬がリリース予定です。


仕事から帰り、疲れているけど頑張ってコーディングしていたら、楽しくて、興奮して眠れなくなり、寝不足な毎日でした。でも完成です。

もちろんまだ共同運営のお話しをくださった方がテストをして、手直しが残っていますが、第一弾完成です!!!

Perlコーディング

ディレクトリ作成

2007年12月24日
クリスマスイブですね。


Perlでディレクトリを作成する方法です。

$result = mkdir("ディレクトリのパス", 0775);
if($result == 0){
 $err_msg = "ディレクトリを作成できませんでした。";
}


0775はパーミッションです。

Perlコーディング

突然Perlのcgiが動かなくなった

2007年12月22日
本当に突然、そうつい1分前まで動いていたPerlで作ったcgiが動かなくなりました。

原因は不明。なにも変えていないのに突然です。


あと少しでテストが終わるところだったのに・・・・ サーバー管理会社へ問い合わせたけど、返事無し。管理会社のWebページが変わっていたから、障害対応はしている模様。なのに返事がないということは、こちらのPCのせいか、ブラウザか?


でもブラウザを変えても動かなかった。ということは?何?


拡張子cgi以外は動いています。


一体なに?? 何が悪いのか・・・


果報は寝て待てというし、とりあえず寝てみようかな。

Perlコーディング

サブ関数への参照渡し

2007年12月20日
サブ関数へ引数を参照渡しする方法です。
参照渡しなので、サブ関数で変更を加えると、呼び出し元関数の値も変更されます。


呼び出し元
&subFunction(*hikisuu);

サブ関数
sub subFunction() {
 local(*hikisuu) = @_;
}


呼び出し元、サブ関数で変数の前の記号を*にします。

Perlコーディング

配列・変数初期化

2007年12月19日
Perlでは、配列と変数の初期化はundef関数で行います。

 undef $hensu;
 undef @hairetu;

大きな配列が必要なくなったとき、undefでつぶした方がいいでしょう。

Perlコーディング

インターネット上のファイル取得

2007年12月17日
Perlでは、外部ドメインのページを取得する関数がないので、処理を書かなければいけないようです。PHPでは内部も外部もfopenで取得できるのですが、Perlはそうはいかないようです。

URLからホスト名とファイルを分け、ソケットをオープンして接続して内容を取得しなければいけません。取得に成功したら、htmlの特殊文字をエスケープします。



呼び出し元
&gePage("取得したいURL")

サブ関数
sub getPage{
 use Socket;

 $url = shift @_;
 my $host;
 my $file_path;

 $host = $url;

 $host =~ s/http:\/\///g;
 $host =~ s/https:\/\///g;
 @domain = split(/\//, $host);

 $file_path = $host;
 $file_path =~ s/@domain[0]//g;

 $host0 = @domain[0];
 $port0 = getservbyname("http", "tcp");

 $ipaddr = inet_aton($host0) or return "ホスト名検出エラー($host0)<br>\n";
 $sock_addr = pack_sockaddr_in($port0, $ipaddr);
 socket(SOCK, PF_INET, SOCK_STREAM, 0) or return "ソケット作成エラー($ipaddr / $port0)<br>\n";
 connect(SOCK, $sock_addr) or return "サーバー接続エラー($ipaddr / $port0)<br>\n";

 select(SOCK);
 $|=1;
 select(STDOUT);

print SOCK << "END_OF_DOC";
GET $file_path HTTP/1.0
Host:$host0
Connection:close

END_OF_DOC


 while(<SOCK>){
  last if m/^\r\n$/;
 }
 while(<SOCK>){
  while(s/</</is){ };
  while(s/>/>/is){ };
  while(s/\r\n|\r|\n/<br>/is){ };
  $page .= $_;
 }
 close SOCK;

 # エスケープ
 $page =~ s/&/&/g;
 $page =~ s/"/"/g;
 $page =~ s/</</g;
 $page =~ s/>/>/g;
 $page =~ s/<br>/\r\n/g;
 $page =~ s/<br>/\r/g;
 $page =~ s/<br>/\n/g;

 return $page;
}

Perlコーディング

fromオブジェクトのpostとget

2007年12月10日
fromに入力した値や、URLに引数として付加した値(クエリ情報と言うようです)は、どのような形で受け取れるのでしょうか。

PHPの場合、変数に値が代入されて渡ってきます。PHP5ならば、$_POSTや$_GETに配列として代入されています。
例えば、
<form method="post">
<input type="text" name="hensuu" value="">
<input type="submit" value="OK">
</form>
の場合、テキストに入力された値は、$hensuu(または$_POST['hensuu'])で参照できます。
$_POSTと$_GETが扱いづらければ、
extract($_POST);
で$_POSTの添え字を変数名とした変数にその値を入れてくれます。
例えば、$_POST['mode']='edit' なら、$mode='edit' となります。便利~


ところが、Perlはこのような機能はなく、自分で何とかしなければいけません。
$ENV{'REQUEST_METHOD'}に【POST】で渡ってきたのか、【GET】で渡ってきたのか入っています。
POSTの場合、read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); で$bufへ、
GETの場合、$buf = $ENV{'QUERY_STRING'};
で値を受け取れます。

受け取った値は、
hensuu1=value1&hensuu2=value2&・・・
の形式です。この値は、エンコードされているので、デコードします。
$char =~ tr/+/ /;
$char =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2", $1)/eg;
($char =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1) )/eg; の方が一般的だとか。理由はまだ理解にいたらず・・)

まずは【&】で分解します。
hensuu1=value1
hensuu2=value2
 ・
 ・
 ・

次に【=】で分解します。
これを配列などに入れてやれば利用しやすくなります。
$in{'hensuu1'} = value1
$in{'hensuu2'} = value2

これでやっと変数名とその値が得られます。めんどくさっ。


探せばライブラリがどこかにあると思うのですが、サンプルで貰ったコードを利用させてもらってます。

Perlコーディング

比較演算子

2007年12月08日
数値と数値の比較は
 $val1 == $val2 $val1と$val2は等しい
 $val1 != $val2 $val1と$val2は等しくない
 $val1 > $val2 $val1は$val2より大きい
 $val1 < $val2 $val1は$val2より小さい
 $val1 >= $val2 $val1は$val2以上
 $val1 <= $val2 $val1は$val2以下
 条件1 && 条件2 条件1かつ条件2
 条件1 || 条件2 条件1または条件2


文字列と文字列の比較は
 $val1 eq $val2 $val1と$val2は等しい
 $val1 ne $val2 $val1と$val2は等しくない
 $val1 gt $val2 $val1は$val2より大きい
 $val1 lt $val2 $val1は$val2より小さい
 $val1 ge $val2 $val1は$val2以上
 $val1 le $val2 $val1は$val2以下
 $val1 =~ /$val2/ $val1に$val2が含まれている
 $val1 !~ /$val2/ $val1は$val2が含まれていない

Perlコーディング

ファイル関係

2007年12月04日
ファイルが存在するかどうかのチェックは、
$result = -e $path;
$result が1なら存在します。

ファイルサイズは
$result = -s $path;


stat関数を使うと、他のファイル情報も取得できます。
@data = stat('filename');
 $data[0] デバイス番号
 $data[1] iノード番号
 $data[2] パーミッション
 $data[3] リンク数
 $data[4] 作成者のユーザID
 $data[5] 作成者のグループID
 $data[6] 特殊ファイルのデバイス識別子
 $data[7] バイト数
 $data[8] 最終アクセス日時
 $data[9] 最終更新日時
 $data[10] 作成日時
 $data[11] ブロックサイズ
 $data[12] ブロック数
のようです。日時は1970/01/01からの秒数で返ってくるのでlocaltimeで人間にわかる日時に変換します。

Perlコーディング

htmlファイルからcgiの呼び出し

2007年12月03日
cgiを実行するには、ブラウザでcgiファイルにアクセスしたり、コマンドプロンプトから実行したりします。
ブラウザからcgiファイルにアクセスするには、通常のhtmlファイルと同じで、 http://・・・・・・・/jikkou.cgi とすればOKです。


では、htmlファイルからcgiを呼び出すにはどうすればいいのでしょうか。
つまり、 http://・・・・・・・/access.html にアクセスしたとき、cgiを実行したいのです。

貰った仕様書を見ていると、imgタグを使うようにとの指示だったので、とりあえずやってみました。
<img src="jikkou.cgi" width="1" height="1">

動きました。こんなんでいいのでしょうか。これって一般的な方法なんだろうか・・・?

Perlコーディング

条件判断処理

2007年12月01日
なんと!perlにはswitch構文がないそうです。vb6で言われていることですが、if文を使うよりswitchの方が処理が早いそうなのででうが、perlにはないのだそうです。まぁなくても困りそうにはないのですが。


if文
if (条件判断) {
}
elsif (条件判断) {
}
else{
}
気をつけなければいけないのは、elsifのつづり。elseifではないです。vbでもPHPでもelseifだったので、手が迷います。


unless文
unless(条件判断) {
}
if文とは反対の意味を持っています。

$cnt=0;
for($cnt;$cnt<1000;$cnt++){
 unless($cnt>5) {
  $tmp[$cnt] = $cnt;
 }
}
の場合、$cntが5より大きくない場合、つまり、5になるまで処理されます。@tmpには0~5までの値が入ります。
他の言語でも見たことあるけど、使ったことはないような・・・ ifで処理してしまうのは私だけ??

Perlコーディング

ループ処理

2007年11月30日
for文
for ($cnt=0; $cnt<$num; $cnt++) {
 ・
 ・
}


foreach文
foreach $value (@array) {
 ・
 ・
}
配列@arrayの各値を処理できます。処理している値が$valueに入ります。


while文
while (評価) {
 ・
 ・
}
評価が真の間処理を繰り返します。


until文
until (評価) {
 ・
 ・
}
評価が真になるまで処理を繰り返します。


ループを抜ける関数に、next、last、redo、gotoがあります。

next:現在のループ処理を終了し、直ちに次のループへ。 PHPのcontinueに相当。
last:現在のループ処理を直ちに終了。PHPのbreakに相当。
redo:現在のループ処理からただちにループの先頭へ。
goto:現在のループ処理からただちに指定されたラベルに飛ぶ 。

Perlコーディング

多次元配列

2007年11月29日
多次元配列が使えるようになったのは、perl5からだそうです。4までは使えなかったということ。へぇ・・・

といっても、多次元配列は他の配列への参照を保持しているだけだそうです。
print @itijigen;
とすると、@itijigenの中身が全て画面表示(あるいはファイル出力)されますが、多次元配列を同じように表示しようとしても参照値が表示されてしまいます。


$tajigen{'name'}[$rows]
で多次元配列に値を入れることができます。ほかにも色々方法はあるようですが、PHP使いにはこれが一番わかりやすかった。とりあえずこれでコーディングを進めます。

配列の添え字に文字列が使えるのはPHPと同じ。添え字が文字列の場合は括弧は{}を、添え字が数字なら括弧は[]のようです。

Perlコーディング

文字列操作関数

2007年11月28日
文字列の長さというか、バイト数が返ってきます。jperlなら日本語対応?
length($str);
 $str = "abc" なら3
 $str = "あいうえお" なら10
 $str = "あaいiう" なら8


部分文字列
substr($str, offset, length);
 $str = "あいうえお"  offset=0 length=1 なら1バイト分に該当する文字
 $str = "あいうえお"  offset=0 length=2 ならあ
 $str = "abcdefg"  offset=3 length=4 ならdefg
 $str = "abcdefg"  offset=3 length=5 でもdefg
 $str = "abcdefg"  offset=2 ならcdefg


文字列分割
@array = split(/ pattern /, $str);
 $str = "2007-11-28" pattern="-" なら array[0]=2007 array[1]=11 array[2]=28
 $str = "2007/11/28" pattern="\/"(/の場合は\でエスケープ) なら array[0]=2007 array[1]=11 array[2]=28 
 patternは正規表現もできる


フォーマット
print()と同じフォーマットだけど、ファイルや画面出力はしない
$yyyymmdd = sprintf("%04d/%02d/%02d", $year, $month, $day);
 $year=2007 $month=11 $day=28 なら 2007/11/28
 $year=2007 $month=12 $day=1 なら 2007/12/01


文字列検索
先頭から検索し、最初に見つかった位置を返す
index($str, substr, position);
 $str = "abcdefgabc" substr="f" なら5
 $str = "abcdefgabc" substr="b" なら1

後ろから検索し、最初に見つかった位置を返す
rindex($str, substr, position);
 $str = "abcdefgabc" substr="f" なら5
 $str = "abcdefgabc" substr="b" なら8

Perlコーディング

ディレクトリ内のファイル

2007年11月27日
ディレクトリ内の各ファイルへのアクセスは
opendir(DIR, "ディレクトリ");
while ($file = readdir(DIR)) {
}
closedir(DIR);
でできます。

opendir(DIR, "ディレクトリ");で目的のディレクトリをオープン、
readdir(DIR)でディレクトリ内のファイル名が取得できます。$fileにファイル名が代入されます。
最後にclosedir(DIR);でディレクトリのクローズを忘れないように。


ファイル削除は
unlink($file);
で行います。

$fileに配列を渡すと、複数のファイルを削除できます。
@files = (file1,file2,・・・);
unlink(@files);


$del_num = unlink(@files);
とすると、削除に成功したファイル数が$del_numに返ってきます。

Perlコーディング

x日後の日付を求める

2007年11月25日
指定した日付からx日後の日付を求めてみます。
Perlでは、1970/01/01 000:00:00からの秒数で日付を計算します。

まずは、現在日を求めてみます。昨日はstrftimeを使って求めましたが、今日は1970/01/01 000:00:00からの秒数から計算する方法を用います。
($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time);
とすると現在日時が得られます。
表示してみると(実行日2007/11/25)、
$day = 25
$month = 10
$year = 107
が返ってきています。つまり、月には1を足し、年には1900を足すと現在日になります。


次に、現在日時を1970/01/01 000:00:00からの秒数に直してみます。timelocal関数を使います。
localtime(time)で求めた現在日をtimelocal関数で秒数に直してみます。

($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time);
$times = timelocal($sec, $min, $hour, $day, $month, $year);
timeと$timesの値を表示してみると、同じであることがあります。これは当たり前ですね。

では、$yearに1900を足して秒数を求めてみます。
($sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst) = localtime(time);
$times = timelocal($sec, $min, $hour, $day, $month, $year+1900);
timeと$timesの値は同じです。

つまり、$monthは5月なら4を、11月なら10をという具合に、1を引いた値を引き渡します。年は1900を足しても足さなくてもよいようです。


それでは、指定した日のx日後(前)の日付を取得してみます。


指定した日のx日後(前)の日付を取得する関数を作成しました。
Perlでは、1970/01/01 000:00:00からの秒数で日付を計算します。timelocal関数を使うと計算できます。
2007/11/20の5日後の場合、
$year = 2007;
$month = 11;
$day = 20;
$times = timelocal(0, 0, 0, $day, $month-1, $year);
で 1970/01/01 00:00:00 から 2007/11/20 00:00:00 までの秒数が求められます。

5日後なので、5日間の秒数は
$x = 5;
$num = 60 * 60 * 24 * $x;
で求められます。
$times + $num の秒数を、日付に直せばOKです。

( undef, undef, undef, $day, $month, $year ) = localtime($times + $num);
$year += 1900;
$month += 1;

で2007/11/20の5日後の日付がわかります。

x日前の場合、$xに負の値を渡せばOKです。


sprintf関数を使って、日付の書式をかえてやります。
yyyymmdd書式にするためには
$yyyymmddJ = sprintf("%04d%02d%02d", $year, $month, $day);



自由に使えるモジュールも公開されています。
Date::Simpleモジュール

Perlコーディング

現在日時の求め方

2007年11月24日
現在日時を取得するときは、
use POSIX 'strftime';
$now = strftime "%Y/%m/%d %H:%M:%S", localtime;
なら 2007/11/24 22:10:00 の書式で返されます。

use POSIX 'strftime';
$now = strftime "%Y%m%d", localtime;
なら 20071124、

use POSIX 'strftime';
$now = strftime "%y%m%d", localtime;
なら 071124
となります。

Perlコーディング

perlエディタ

2007年11月23日
ずっと探していた使いやすいperl用のエディタですが、まぁこれならというものがやっと見つかりました。

条件は、
・コーディングに使うファイルを全て登録できるプロジェクト機能
・変数、関数、組み込み関数、文字など色分けができること、また色が選べること(きつい色だと目がチカチカする)
・プロジェクト内検索ができること
・文字コードが指定できること、また簡単に指定、確認できること
・複数ファイルを開いても、アプリケーションが複数開かないこと
・ブックマーク機能があること
etc・・・

MKEditorです。各言語の強調、色分けファイルも公開されています。つまり、自分でかなりアレンジできるということ。

ただ、2点、どうしてもできないことが。私の設定が悪いのではないのだと思いますが。
・変数や配列($、@)で始まる文字列の色が変えられないこと
・【"】、【'】をエスケープしている場合、色分けがうまくいかない

仕方ないので、$、@だけを色分けしています。2番目はどうにもなっていません。
ちょっと不便。

Grep検索があるのですが、プロジェクト内検索がありません。ファイル内とフォルダ内の検索は可能ですが、プロジェクトに登録したファイルのみ検索することはできないようです。

また、行選択でコメント化する機能がないのも不便です。Perl専用のエディタではなから仕方ないのかな。マクロで対応できるのかな・・・?

ちょっと残念。というか、私にこんなソフトが欲しいという強いイメージがあるので、ちょっと違っても使いにくく感じるんだと思います。


しばらくお世話になろうと思います。


以前にEclipseが気になると書きましたが、こちらも調べてみました。私が想定していたより規模の大きいソフトのようです。会社で複数人のプロジェクトも管理できるようなソフトのようなので、とりあえず保留です。

Perlコーディング

リダイレクト

2007年11月22日
1.認証画面で、パスワード認証
2.クッキー発行
3.トップページへジャンプ
としたいので、リダイレクトを使ってみることにしました。

httpヘッダに、
print "Location: リダイレクトしたいURL\n\n";
と書けばリダイレクトしてくれます。


これはクッキー発行の直後に行いたいので、
print <<EOT;
Content-type: text/html
print "Set-Cookie : cookie_name=cookie_value;\n\n";
print "Location: リダイレクトしたいURL\n\n";

としたのですが、これは画面に
print "Location: リダイレクトしたいURL\n\n";
と表示されてしまい、どうしてもうまく動作しません。


考えた挙句、htmlのヘッダに
<meta http-equiv="Refresh" content="リダイレクトまでの秒数;URL=リダイレクトしたいURL">
を書き加えることにしました。

1.認証のために認証画面を表示したときは、書き込まない。
2.パスワードを入力してボタンをクリックすると、再度認証画面のファイルを読み込み、パスワード確認
3.正しければクッキー発行と上のメタタグを出力

print <<EOT;
Content-type: text/html
print "Set-Cookie : cookie_name=cookie_value;\n\n";
空行
htmlソース

これでクッキーを発行後、目的のURLにリダイレクトできます。
リダイレクトまでの秒数を0にすると、再度認証画面が表示されることはありません。

Perlコーディング

クッキー発行、クッキー読込

2007年11月21日
クッキーを発行して、認証に使います。

1.ログインが完了でクッキー発行
2.それ以降のページではクッキーを読み込んで、セットされていれば表示、されていなければ表示しない

とします。


まず、クッキー発行。
Cookieの属性は
・名前
 必須。クッキーの名前と値を設定します。
・ドメイン
 クッキーを発行するドメインを指定します。
・パス
 Cookie情報の取得を許可するURLパス情報を指定します。
・有効期限
 クッキーの有効期限を指定します。書式は、Fri, 21-Nov-2007 23:59:59 GMT
 指定しなければ、ブラウザが閉じられるまでが期限になります。
・セキュア接続フラグ
 フラグを立てると、サーバーとの接続がセキュアであるときのみ、クッキーが有効になります。
があります。

構文は
Set-Cookie : 名前=値; expires=日付;path=パス; domain=ドメイン名; secure
です。日本語や【"】、【'】、【;】が含まれる場合はエンコードします。
変数$cookieをエンコードするときは
$cookie =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg;
です。


今回は簡単な認証に使うだけなので、名前のみ指定します。ブラウザを閉じたらセッションを閉じたいので、有効期限も無指定です。

クッキー名:cookie_name
値:cookie_value
をセットします。
Set-Cookie : cookie_name=cookie_value;\n\n

これをヘッダにprint文で書き込みます。\n\nと\nを2つ続けて出力します。Set-Cookieの後ろは空行が必要なようです。

print <<EOT;
Content-type: text/html
print "Set-Cookie : cookie_name=cookie_value;\n\n";
空行
html本体


次は、クッキー取得。
発行したクッキーは$ENV{'HTTP_COOKIE'}で参照できます。各属性は【;】で、名前と値は【=】で区切ることができます。発行時はエンコードしたので、取得時はデコードします。

クッキー取得サブ関数です。$cookie{'クッキー名'}で値が参照できます。
sub getCookie {
 $cookie_name = shift @_;
 foreach (split(/;/, $ENV{'HTTP_COOKIE'})) {
  ($name, $value) = split(/=/);
  $name =~ s/\s//g;
  $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
  $cookie{$name} = $value;
  return $cookie{$cookie_name};
 }
}

今回セットしたCookieの場合、$cookie{'cookie_name'}にcookie_valueが入っています。


参考になるサイト
Perl講座 -Smart
簡単CGI クッキーを使おう

Perlコーディング

サブ関数を外部ファイルへ

2007年11月20日
昨日作ったサブ関数を、色々なファイルから使えるように、外部ファイルへ書き出すことにしました。


関数部分を切り取って、外部ファイルへ貼り付けて保存します。ファイル名は【function.pl】とします。

関数を使うには、使う側のファイルの先頭で(perlのパスの後ろ)
require 'function.pl';
とするとファイルが読み込まれ、関数が使えるようになります。

コールは、同じファイルにあるときと同じで、
&関数名;
です。


でも、これでは動きませんでした。他のファイルを見ていると、function.plの一番後ろに、【1;】が付いています。試しにつけてみたら、動きました。なんだこの【1;】は・・・


調べてみると、どうやら戻り値が真であるという意味だそうです。

Perlコーディング

サブ関数

2007年11月19日
今日はサブ関数作成に挑戦です。

コール
&function_name();

関数
sub function_name {
 ・
 ・
 ・
}


Perlでは、引数は標準で参照渡しされるようです。

&function_name(hikisu1, hikisu2);

sub function_name {
 $_[0];
 $_[1];
 ・
 ・
 ・
}

引数は@_という特別な変数の中にあるので、順番に、$_[0]、$_[1]、・・・で参照できます。関数内で$_[0]や$_[1]の値を変更すると、呼び出し元の変数も変更されます。


これを値で渡したい場合(値渡し)

&function_name(hikisu1, hikisu2);

sub function_name {
 my ($val1, $val2) = @_;
 ・
 ・
 ・
}

function_nameの中だけで有効な変数に値をコピーしているので、コール側の値は変わりません。

my ($val1, $val2) = @_; は複数の引数を一度に代入していますが、
$val1 = shift @_;
$val2 = shift @_;
とすると1つ1つ指定できます。

また、Perlでは変数は宣言(my)しない限り、Globalです。
ということは、引数が変数で参照渡ししたいときは、わざわざ引数で渡さなくてもよいということ。でもきっともっと奥の深い何かがあるはず。


sub function_name {
 my ($val1, $val2) = @_;
  処理1
 return (戻り値);
  処理2
}

の様にreturnを使うと、処理2は行わず、戻り値をコール側に返して、関数を終了します。
コール側は
$modori = &function_name();
で戻り値を受け取ります。

Perlコーディング

print文とヒアドキュメント

2007年11月17日
ファイルに書き込むときは
 print FILEHANDLE "書き込む内容";
とprint文にファイルハンドラを続けて書き、ファイルに書き込みました。

ファイルハンドラを指定しなければ、標準出力されます。ブラウザから呼び出されていればブラウザに、コマンドプロンプトから呼び出されていればコマンドプロンプトに出力されます。


このprint文を使って、ブラウザに文字を表示します。
たくさん文字を表示したいときは、ヒアドキュメントを使うと便利です。

 print <<EOT;
 出力したい文字列
 EOT

こうかくと、<<EOT;とEOTで囲まれた文字列が出力されます。出力したい文字列は【"】や【'】で括る必要はありません。なので、【"】を出力させたい場合、【\】でエスケープする必要もありません。便利ですね。

ヒアドキュメントはprintだけでなく、変数に文字を代入するときも使えるそうです。
 $hensu = <<EOT;
 代入したい文字列
 EOT



ところが、このprintとヒアドキュメントに随分悩まされました。なかなか表示されなかったのです。結局、EOTの前にタブを入れていたのが原因だったようです。こんなことで・・・


<<'EOT';
とすると、出力したい文字列の中に変数があっても、その値を出力しなくなります。
例えば、$hensuに"変数"という文字が代入されていたとします。

 print <<EOT;
 $hensu
 EOT
の場合は、【変数】と表示されます。

 print <<'EOT';
 $hensu
 EOT
とすると、【$hensu】と表示されます。


<<`EOT`;
とすると、文字列をコマンドとして実行し、結果を返してくるそうです。


知らなかったのですが、PHPでもヒアドキュメントは使えるそうです。
PHPの場合、
 print <<< EOT
 出力したい文字列
 EOT;
です。perlとは少し構文が異なります。

Perlコーディング

ファイルの入出力

2007年11月16日
今日はファイルの入出力です。

読み込み用にオープンする場合は、
 open(FILEHANDLE,"filename");
またはfilenameの前に<をつけて
 open(FILEHANDLE,"<filename") ;
とします。

 @file = <FILEHANDLE>;
とすると、ファイルの内容が配列fileに代入されます。

書き込み用にオープンする場合は、
 open(FILEHANDLE,">filename");
とします。
 print FILEHANDLE "書き込む内容";
でファイルに書き込みます。

追記用にオープンする場合は、
 open(FILEHANDLE,">>filename");
です。


ファイルをクローズするには
 close(FILE);
です。


また、Perlには
 open(FILEHANDLE, "filename") or die "ファイルが開けません";
という書き方があるようです。
 open(FILEHANDLE, "filename")
でオープンに成功したらtrue、失敗したらfalseが返ってきます。trueが返ってきたら、or以降は実行されません。
falseが返ってきたら、or以降が実行され、『ファイルが開けません』と表示して処理を全て中止します。

のはずなのですが、ファイルが開けなくても、メッセージが表示されません。なぜだ・・・

Perlコーディング

【n】、【"】、【'】の関係

2007年11月15日
Perlは全くの初めてです。いままではもっぱらWeb系のコーディングはPHPでした。


まずはエディタ探しからです。VectorやGoogleからPerl用の使いやすいエディタはないものかと探したのですが、なかなかこれ、というものにいきあたりません。

PHPを書くときはPHPエディタを使ってます。プロジェクト管理もできるし、プロジェクト内の検索もできるし、とても気に入ってます。ただ1つ不満なのは、ブックマーク機能がないことです。
eclipseも気になってます。


PHPエディタのようなPerlエディタがないか調べているのですが、見当たりません。エディタの良し悪しで作業効率がぐっと違ってくるので、自分が使いやすいものを早く見つけたいです。


さて、コーディングの話です。
コーディングを始めてすぐに困ったことが。改行コードである\nが入らないのです。【"】を文字としてブラウザに出力したいので、変数そのものを【'】で括っていたのですが、これがいけなかった。【'】の中では\nは入らないのです。

【"】を含む文字列を、【"】で括りたい場合、【"】を【\"】とエスケープする方法もあります。なんだ、これっていつもPHPで使っているじゃぁいか・・・

つまり、
<input type="text" name="id" value="1">\n
を変数に代入したい場合、
$hensu = "<input type=\"text\" name=\"id\" value=\"1\">\n";
とします。
$hensu = '<input type="text" name="id" value="1">\n'
とすると、\nが文字として画面に出力されてしまいます。