PerlとRubyがくしゅう帳

プログラミングの勉強会の参加記録や学んだことなど。 twitter ID : @tomcha_です。 最近は主にPerl関連の勉強会やコミュニティに参加しています。

2013年03月

1月のPerl鍋で作りかけていた(その後放置していた?)コードをの続きを色々いじくってみてハマった事などを。

今回改造してハマったこと、思ったこと
  • 前回、「3日毎」を表現するために日付のシリアル値を計算していたところを、Time::Pieceの秒数で管理する事にした。60*60*24を足して3日後を表現し、処理のタイムラグを考慮するため、Time::Piece::localtime()とTime::Piece->strptime(日付,フォーマット)の差を足したら、約8時間ずれた秒数が帰ってきた。strtimeで生成する時は、タイムゾーンが標準時間になるので、localtime(Time::Piece->strptime(日付,フォーマット))で直してやらないとタイムゾーンがずれる。
  • Proc::Daemonは、Perl Tipsさんのブログをほぼ丸写しさせてもらいました。while(1)とsleepとは、原理は意外と簡単なものでできてるんだなぁと思った。ただ、3日毎にメール送るだけのサービスなのに、ローカル環境で試してみたら、プロセスのメモリが2メガも使ってるのでびっくり。コードがまずいのか?
とりあえず、コードはとりあえず完成させたので、いよいよ次はさくらvps借りて運用させるところまで来た!ドットインストールにさくらVPSの使い方講義が上がってるので、次はそれにチャレンジします。
 

Perlのオブジェクト指向について、Acme::MomoiroCloverのソースコードを題材に研究させてもらいました。
とりあえず、途中まで読んで考えたことを自分用にメモ。


モジュールの使い方・・・まず、モジュールをuse。
変数にモジュール名->newを代入。newメソッドの戻り値がオブジェクトっぽい。
newメソッドを調べてみる。

sub new{
    $class = shift;

引数が無いのにshift?
ググって調べてみると、package宣言以下のサブルーチンを呼び出した時には、自動的に第一引数としてそのオブジェクト自身(今回はパッケージ名からnewを呼び出しているので、パッケージとなる)のリファレンスが設定されるらしい。これをinvovcantという。
そういう仕様である事を理解。と言うことは、引数付きでオブジェクトを生成する時は、第二引数からが実際に渡したい引数になるので注意。

    my $self = bless{members => []},$class;
 
最終的にnewメソッドでは、$selfをreturnしているので、$selfが生成されたオブジェクトそのもの(のリファレンス?)の様だ。このコードでは、$selfにbless関数の戻り値を代入しているので、bless関数を調べてみると、、、

第一引数であるリファレンスと第二引数のクラスを関連付ける関数

第一引数は、membersをキーとした要素が空の配列である1ペアのみのハッシュ、第二引数に最初にshiftしたこのパッケージそのものを渡しているので、ここでは、オブジェクトのインスタンス変数をハッシュで、インスタンスメソッドをpackage以下のサブルーチンで表現したものを$selfに参照させてオブジェクトを表現しているっぽい。

$selfは予約後ではなくて、慣例的に使っているのだろうか?
$selfはハッシュのリファレンスとメソッドのリファレンスが格納されている、それをオブジェクトとして表現しているのだろうか?

        次の$self->_check();は、データの変更に対応させるものっぽいので、今回はややこしいので飛ばして、次の$self->_initialize;のコードでデータの初期化をしていると推測。

        _initializeを調べてみる。
        $self = shift;
今回は、$selfからのサブルーチン呼び出しなので、invocant、第一引数はpackageではなく$selfそのものになる。perlでの->での関数呼び出しの書式って、実はオブジェクトは関数名をキーとした関数のリファレンスのペアのハッシュであり、->でハッシュを展開して最終的にサブルーチンを呼び出し(参照)ている仕組みなのか?

            と仮定するとしっくりくる。

で、次のコードでpackageの冒頭で代入されている@members配列をforで回して、$module_name文字列を作成し、それをrequireしている。

requireとは、useと同じように別のモジュールを使う為の宣言だが、useとの違いは随時読込であること。必要なときにだけ読み込むのでメモリの節約となる。使い分けを覚えておこう。

次のpushのコードを調べてみる。
push先 @{$self->{members}}は、$selfハッシュ(blessされたやつ)をmembersをキーとした要素、即ちbless関数の[]そのものを指すのだろうか。
        
で、$module_name->new はrequireしたパッケージのnewメソッドなので、それを見る必要があり。おそらく、$module_nameに記述された個別のオブジェクトを配列にpushしていく、そうすると、$selfのmembersに各オブジェクトのリファレンスが配列として格納されていく。
   
        $self = {members =>
            [
                hoge,
                fuga,
                piyo,
                ...
            ]
        }
       
というオブジェクトが完成する。で、blessされたパッケージのsubルーチン群もハッシュに入ってるのではないだろうか?Data::Dumperで確かめてみる価値あり?
->確かめたら、blessのコードが吐出されてた


            と仮定してみる。
            
この辺りの知識って、はじめてのperlには載ってなかった。続初めてのperlに載ってるのか。もう少しじっくり研究してみる。なかなか奥深く、難しい。

このページのトップヘ