Re:

のあんのブログ

カテゴリ:開発 > perl

PHPでいうところの

$list = array("id"=>"1","name"=>"hoge","created"=>"2009-09-29 00:00:00");

なんて連想配列をperlにてハッシュで表現した場合、each関数などでループ処理すると順番に取り出しますが、その順番は上記の記述における順番とは違い、期待とは違う場合があります。

PHPの場合なら

foreach($list as $key => $val){
print "$key:$val<br />\n";
}

結果

id:1
name:hoge
craeted:2009-09-29 00:00:00

となりますが、perlの場合

while(($key,$val)=each(%list)){
print "$key:$val<br />\n";
}

結果

created:2009-09-29 00:00:00
name:hoge
id:1

とか。


そこで、期待したとおりに出力させるためにモジュールをインストール!


そのモジュールがTie::IxHashです。

CPANにてインストールしました。

# cpan

初めに初期設定メッセージがいろいろ出てくるので、基本はデフォルトのままEnterしていけば良いと思います。

必要なプログラムパスを確認してくるところで、gzip, tar, make, lynxは最低限あるように配慮して続け、Parameters for the 'make install' command? []と確認してくるところでUNINST=1と入力し、"古いモジュールがあった場合には消す"オプションを設定します。

ちなみに、先に設定してしまっていた場合は、

# cpan

> o conf make_install_arg UNINST=1

として設定を変更可能。(なお o conf で一覧が見られ、同様にして他も変更できます。)

その後もproxy設定不要ならそのままEnter、地域やミラーサーバは適宜選択。

以上でCPANの利用準備完了です。


>install Tie::IxHash

で、目的のモジュールがインストールできます。

抜ける場合は q または Ctrl+D で。


あとはモジュールをロードしてハッシュを設定すれば、期待どおり挿入順に取り出せます。

#!/usr/bin/perl

use Tie::IxHash;

tie %list,'Tie::IxHash';

%list = ('id'=>'1','name'=>'hoge','created'=>'2009-09-29 00:00:00');

while(($key,$val)=each(%list)){
print "$key:$val<br />\n";
}


ドキュメントやサンプルは以下を参照。

http://search.cpan.org/~gsar/Tie-IxHash-1.21/lib/Tie/IxHash.pm

普段からプログラムしてないと、基本的なこともままならなかったり。

と言うわけで、perlからMySQL接続時のトラブルを下準備と共にメモ。


・perl構文エラーがあると500 Internal Server Errorとなるだけで、デフォルトではエラー箇所の特定が不便(Apacheのエラーログを見なきゃなので)

・上記に応えるべく、CGI::Carpモジュールでブラウザへ表示させる
use CGI::Carp qw(fatalsToBrowser);

・perl-DBI、perl-DBD-mysqlのインストールでMySQLの使用準備

・MySQL、perl-DBD-mysqlのインストールは、ソースまたはパッケージのインストール違いにより若干設定が必要


今回は一番最後の箇所でつまづきました。

MySQLをソースからインストールしていたので、ソケットファイルがデフォルトのまま/tmp/mysql.sockだったこと、perl-DBD-mysqlをパッケージによりインストールしたので/var/lib/mysql/mysql.sockだったことにより、接続できなかった…という。


$dbh = DBI->connect(〜) or die $DBI->errstr;

すると

Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'

なんて怒られてしまいます。

なので、my.cnfを変えても良いかもですけど、解決策としてconnect()の第一引数に与えるデータソースでソケットを指定する方法をとります。

connect("DBI:mysql:$database;mysql_socket=/tmp/mysql.sock",$user,$password)


なお、データソースの記述方法はいくつかあるので、適当な記述を。

5系のマニュアルがなかったので4系のマニュアルを読むと、

MySQL :: MySQL 4.1 リファレンスマニュアル :: 11.5.2 DBI インタフェース

ページにあるように、ユーザー名とパスワードのハードコードを避け、ソケットの設定も含めユーザ毎の設定ファイルmy.cnfをmysql_read_default_fileで読み込ませるのが良さそうです。

PHP、PHP、PHP・・・ときましたが、最近perlです。

PHPの手軽さはないと思うものの、便利であることには間違いない。

便利だけど、触れてなかったから少々難解。


CPANからいろいろとモジュール組み込んで、ようやく目的達成の下準備ができたところでした。


ちょっと悩ましいところは、オブジェクトと言っても単なる名前空間であるに過ぎない的な、PHPでオブジェクト指向を意識するようになってきてた脳には、なんかとっつき難い状態に陥ったことでした・・・。

という訳で、MVCなことは置いといて、素直にプログラムしようと思います。


(´・ω・`)

↑このページのトップヘ