Perl で、時刻のシリアル値を取得したい。

Time::Local モジュールを利用する。localtime や gmtime の逆を行う。
use Time::Local;
#!/usr/bin/perl

use Time::Local;

$time = timelocal($sec, $min, $hour, $day, $mon, $year);
$time = timegm   ($sec, $min, $hour, $day, $mon, $year);

1;
Time::Local モジュールを利用する。localtime や gmtime の逆を行う。
use Time::Local;
#!/usr/bin/perl

use Time::Local;

$time = timelocal($sec, $min, $hour, $day, $mon, $year);
$time = timegm   ($sec, $min, $hour, $day, $mon, $year);

1;

Perl で、セッション管理をしたい。 (Apache::Session)

Apache::Session を使う。 パフォーマンスを少し測ってみたら CGI::Session よりも若干速いようである。 このモジュールは eval {...}; とセットで使うとよい。 - Perl で、例外処理をするような感じのもの。if($@) {...} のセットで使う。eval にはセミコロン(;) を忘れないこと。 例では、%session を $session としてハッシュで返している。 このモジールを使う利点は、ID の長さを自由に変えられることである。CGI::Session の場合は、ID の長さを変えたければ、自分で書かなければならない。一方で短所は、セッションの有効期限を設定できないこと。そのため、MySQL 中のsessions テーブルに timestamp フィールドを独自に追加して、自身の CGI の中か cron で適宜 reap する必要がある。また、セッションオブジェクト中の個別のデータにも有効期限を設けることはできない (CGI::Session はできる)。それでもこのモジュールが良いのは、パフォーマンスが CGI::Session よりも若干良いのと、ID の長さを変えられるからである。
use DBI;
use Apache::Session;
このモジュールは永続ストレージ (要はセッション情報をずっと溜めておけるデータベース) の種類によっていろいろな種類がある。
Apache::Session::MySQL
Apache::Session::Postgres
Apache::Session::File
Apache::Session::Oracle
Apache::Session::Sybase
Apache::Session::DB_File
Apache::Session::Flex 	実行時にすべてのパラメータを指定する
以下の例では Apache::Session::Flex を使っている。
use DBI;
use Apache::Session::Flex;

$session = _getSession;
print $session->{_sessin_id}

sub _getSession {

    my $db;
    my ($database, $username, $password);
    # 以上の変数には値を入れること。

    $db = DBI->connect("DBI:mysql:$databasename",
                                 $username,
                                 $password
                                 ) || die 'Cannot connect db';

eval {

    tie %session, 'Apache::Session::Flex', $sid, {

        Store      => 'MySQL',
        Lock       => 'MySQL',
        Generate   => 'MD5',
        IDLength   => 32,
        Serialize  => 'Storable',
        Handle     => $db,
        LockHandle => $db,
    };

};  # セミコロンを忘れないこと

if($@)    {    # $@: error message of eval

    return undef;
}

# セッション ID の取得に成功。ここに処理を書く。

    return \%session;

}
Apache::Session を使う。 パフォーマンスを少し測ってみたら CGI::Session よりも若干速いようである。 このモジュールは eval {...}; とセットで使うとよい。 - Perl で、例外処理をするような感じのもの。if($@) {...} のセットで使う。eval にはセミコロン(;) を忘れないこと。 例では、%session を $session としてハッシュで返している。 このモジールを使う利点は、ID の長さを自由に変えられることである。CGI::Session の場合は、ID の長さを変えたければ、自分で書かなければならない。一方で短所は、セッションの有効期限を設定できないこと。そのため、MySQL 中のsessions テーブルに timestamp フィールドを独自に追加して、自身の CGI の中か cron で適宜 reap する必要がある。また、セッションオブジェクト中の個別のデータにも有効期限を設けることはできない (CGI::Session はできる)。それでもこのモジュールが良いのは、パフォーマンスが CGI::Session よりも若干良いのと、ID の長さを変えられるからである。
use DBI;
use Apache::Session;
このモジュールは永続ストレージ (要はセッション情報をずっと溜めておけるデータベース) の種類によっていろいろな種類がある。
Apache::Session::MySQL
Apache::Session::Postgres
Apache::Session::File
Apache::Session::Oracle
Apache::Session::Sybase
Apache::Session::DB_File
Apache::Session::Flex 	実行時にすべてのパラメータを指定する
以下の例では Apache::Session::Flex を使っている。
use DBI;
use Apache::Session::Flex;

$session = _getSession;
print $session->{_sessin_id}

sub _getSession {

    my $db;
    my ($database, $username, $password);
    # 以上の変数には値を入れること。

    $db = DBI->connect("DBI:mysql:$databasename",
                                 $username,
                                 $password
                                 ) || die 'Cannot connect db';

eval {

    tie %session, 'Apache::Session::Flex', $sid, {

        Store      => 'MySQL',
        Lock       => 'MySQL',
        Generate   => 'MD5',
        IDLength   => 32,
        Serialize  => 'Storable',
        Handle     => $db,
        LockHandle => $db,
    };

};  # セミコロンを忘れないこと

if($@)    {    # $@: error message of eval

    return undef;
}

# セッション ID の取得に成功。ここに処理を書く。

    return \%session;

}

Perl の国際化対応: Locale::Maketext

以下のようなファイル構成にする。$ln $ln->maketext('Selected Language'); の、'Selected Language' に対応して翻訳すべきところを MyProject::L10N::ja や MyProject::L10N::en に書けば、自動的に変換してくれる。 ちなみに I18N は Internationalization の I と n の間に18文字あるからだそう。L10N は? => Localization! 使用するモジュール
Locale::Maketext
注:Locale::Maketext は Perl 5.8 以降、標準で組み入れられているため、この仕組みは Perl 標準のものとなっている。
./MyProject/Test.pm
./MyProject/L10N.pm
./MyProject/L10N/ja.pm
./MyProject/L10N/en.pm
./MyProject/L10N/i_default.pm
Test.pm の内容:
package MyProject::Test;

use strict;

use MyProject::L10N;

sub new {

    my $class = shift;
    my $self  = {};

    return bless $self, $class;
}

sub output {

    my $lang = shift;

    my $lh = MyProject::L10N->get_handle($lang) || die "Error: L10N::$lang¥n";
    print $lh->maketext('Selected Language'), "¥n";
}
ja.pm の内容
package MyProject::L10N::ja;

use strict;

use base qw(MyProject::L10N);

our %Lexicon = (
    '_AUTO' => 1,
    'Selected Language'=>'MyProject::L10N::ja に書いてある日本語'
);

1;
en.pm の内容
package MyProject::L10N::en;

use strict;

use base qw(MyProject::L10N);

our %Lexicon = (
    '_AUTO' => 1,
    'Selected Language'=>'English in L10N::en'
);

1;
en_us.pm の内容
package MyProject::L10N::en_us;

use strict;

use base qw(MyProject::L10N::en);

1;
i_default.pm の内容:
package MyProject::L10N::i_default;

use base qw(MyProject::L10N);

1;

__END__
以下のようなファイル構成にする。$ln $ln->maketext('Selected Language'); の、'Selected Language' に対応して翻訳すべきところを MyProject::L10N::ja や MyProject::L10N::en に書けば、自動的に変換してくれる。 ちなみに I18N は Internationalization の I と n の間に18文字あるからだそう。L10N は? => Localization! 使用するモジュール
Locale::Maketext
注:Locale::Maketext は Perl 5.8 以降、標準で組み入れられているため、この仕組みは Perl 標準のものとなっている。
./MyProject/Test.pm
./MyProject/L10N.pm
./MyProject/L10N/ja.pm
./MyProject/L10N/en.pm
./MyProject/L10N/i_default.pm
Test.pm の内容:
package MyProject::Test;

use strict;

use MyProject::L10N;

sub new {

    my $class = shift;
    my $self  = {};

    return bless $self, $class;
}

sub output {

    my $lang = shift;

    my $lh = MyProject::L10N->get_handle($lang) || die "Error: L10N::$lang¥n";
    print $lh->maketext('Selected Language'), "¥n";
}
ja.pm の内容
package MyProject::L10N::ja;

use strict;

use base qw(MyProject::L10N);

our %Lexicon = (
    '_AUTO' => 1,
    'Selected Language'=>'MyProject::L10N::ja に書いてある日本語'
);

1;
en.pm の内容
package MyProject::L10N::en;

use strict;

use base qw(MyProject::L10N);

our %Lexicon = (
    '_AUTO' => 1,
    'Selected Language'=>'English in L10N::en'
);

1;
en_us.pm の内容
package MyProject::L10N::en_us;

use strict;

use base qw(MyProject::L10N::en);

1;
i_default.pm の内容:
package MyProject::L10N::i_default;

use base qw(MyProject::L10N);

1;

__END__

Perl で、CGI::Application を使う

CGI::Application は HTML::Template を統合している。以下は HTML::Template のドキュメントで書かれている例が含まれている。

使用するモジュール

use CGI::Application;

# 要 HTML::Template
# IPC::SharedCache (こちらは任意)

まずは以下のようなディレクトリとファイル構成にする。

./cgi-bin/lib/App.pm
./cgi-bin/templates/test.templ
./cgi-bin/index.cgi

index.cgi の内容:

基本的に App クラスを new して app->run() としているだけである。
BEGIN ブロックのそれはライブラリへのパスを探している。

#!/usr/bin/perl -w

use strict;

my $LIB_DIR;

BEGIN {
    if ($0 =~ m!(.*[/¥¥])!) {
        $LIB_DIR = $1;
    } else {
        $LIB_DIR = './';
    }
    unshift @INC, $LIB_DIR . 'lib';
}

use App;
my $app = App->new();
$app->run();

1;

App.pm の内容。

  1. このモジュールでは、このモジュールから return で返した文字列が出力されるようになっている。よって例では、結果的に $template->output が返す文字列を App オブジェクトから返している。後は自動的に出力される。
  2. $self->mode_param('rm') とあるのはフォームやURL中のクエリ文字列で rm='次に実行すべきメソッド' を指定しろ、ということ。例えば <input type=hidden name=rm value=do_next> みたいな感じである。'rm' がキーワード、メソッド名が値となっている。
  3. $self->start_mode('start') は、見ての通り、このアプリケーションがスタートしたときに実行されるメソッドを指定する。
  4. teardown (=destory と同義) は終了時に呼ばれるメソッド。
  5. このモジュールは CGI、HTML::Template と統合されていて、HTTP ヘッダなども $self->header_props と、CGI と同じように呼び出せる。
  6. HTML::Template については、$self->load_tmpl で HTML::Template オブジェクト (実体はハッシュリファレンス) が取り出せるようになっている。このとき指定できるキャッシュパラメータで、cache、double_cache は Linux など OS の実行プラットフォームに IPC::SharedCache モジュールがインストールされてないと使えない。

#!/usr/bin/perl -w

package App;

use strict;
use base 'CGI::Application';

sub setup {

    my $self = shift;
    $self->mode_param('rm');
    $self->start_mode('start');
    $self->run_modes(
            'start' => ¥&start,
            'end'   => ¥&end
        );
        $self->header_props(-type=>'text/html', -charset=>'utf-8');
}

sub teardown {
    my $self = shift;
    # Post-response shutdown functions
    # ここにはデータベースの切断を書くとよい。
}

sub start {
    my $self = shift;
    my $template = $self->load_tmpl('test.tmpl',  die_on_bad_params => 0,
        path => ['......./cgi-bin/templates'],
#      cache => 1,
#      double_cache => 1,
#      file_cache => 1,
#      file_cache_dir => '/tmp',
#      double_file_cache => 1
    );
    return &template($template);
}

sub end {
}

sub template {

    my $template = shift;

    # the fruit data - the keys are the fruit names and the values are
    # pairs of color and shape contained in anonymous arrays
    my %fruit_data = (
                    Apple  => ['Red, Green or Yellow', 'Round'      ],
                    Orange => ['Orange'              , 'Round'      ],
                    Pear   => ['Green or Red'        , 'Pear-Shaped'],
                    Banana => ['Yellow'              , 'Curved'     ],
                   );

    my @loop;  # the loop data will be put in here

    # fill in the loop, sorted by fruit name
    foreach my $name (sort keys %fruit_data) {
        # get the color and shape from the data hash
        my ($color, $shape) = @{$fruit_data{$name}};
   
        # make a new row for this fruit - the keys are <TMPL_VAR> names
        # and the values are the values to fill in the template.
        my %row = (
               name  => $name,
               color => $color,
               shape => $shape
              );

        # put this row into the loop by reference            
        push(@loop, \%row);
    }

    # call param to fill in the loop with the loop data by reference.
    $template->param(fruit_loop => \@loop);

    # print the template
    return $template->output;
}

1;

test.tmpl の内容:

<HTML>
    <HEAD>
        <TITLE>Fruity Data</TITLE>
    </HEAD>
    <BODY>

        <H1>Fruity Data</H1>

        <TABLE BORDER=1>

            <TR>
                <TD><B>Fruit Name</B></TD>
                <TD><B>Color</B></TD>
                <TD><B>Shape</B></TD>
            </TR>

        <TMPL_LOOP NAME="fruit_loop">
            <TR>
                <TD><TMPL_VAR NAME="name"></TD>
                <TD><TMPL_VAR NAME="color"></TD>
                <TD><TMPL_VAR NAME="shape"></TD>
            </TR>
        </TMPL_LOOP>

        </TABLE>

    </BODY>      
</HTML>

CGI::Application は HTML::Template を統合している。以下は HTML::Template のドキュメントで書かれている例が含まれている。

使用するモジュール

use CGI::Application;

# 要 HTML::Template
# IPC::SharedCache (こちらは任意)

まずは以下のようなディレクトリとファイル構成にする。

./cgi-bin/lib/App.pm
./cgi-bin/templates/test.templ
./cgi-bin/index.cgi

index.cgi の内容:

基本的に App クラスを new して app->run() としているだけである。
BEGIN ブロックのそれはライブラリへのパスを探している。

#!/usr/bin/perl -w

use strict;

my $LIB_DIR;

BEGIN {
    if ($0 =~ m!(.*[/¥¥])!) {
        $LIB_DIR = $1;
    } else {
        $LIB_DIR = './';
    }
    unshift @INC, $LIB_DIR . 'lib';
}

use App;
my $app = App->new();
$app->run();

1;

App.pm の内容。

  1. このモジュールでは、このモジュールから return で返した文字列が出力されるようになっている。よって例では、結果的に $template->output が返す文字列を App オブジェクトから返している。後は自動的に出力される。
  2. $self->mode_param('rm') とあるのはフォームやURL中のクエリ文字列で rm='次に実行すべきメソッド' を指定しろ、ということ。例えば <input type=hidden name=rm value=do_next> みたいな感じである。'rm' がキーワード、メソッド名が値となっている。
  3. $self->start_mode('start') は、見ての通り、このアプリケーションがスタートしたときに実行されるメソッドを指定する。
  4. teardown (=destory と同義) は終了時に呼ばれるメソッド。
  5. このモジュールは CGI、HTML::Template と統合されていて、HTTP ヘッダなども $self->header_props と、CGI と同じように呼び出せる。
  6. HTML::Template については、$self->load_tmpl で HTML::Template オブジェクト (実体はハッシュリファレンス) が取り出せるようになっている。このとき指定できるキャッシュパラメータで、cache、double_cache は Linux など OS の実行プラットフォームに IPC::SharedCache モジュールがインストールされてないと使えない。

#!/usr/bin/perl -w

package App;

use strict;
use base 'CGI::Application';

sub setup {

    my $self = shift;
    $self->mode_param('rm');
    $self->start_mode('start');
    $self->run_modes(
            'start' => ¥&start,
            'end'   => ¥&end
        );
        $self->header_props(-type=>'text/html', -charset=>'utf-8');
}

sub teardown {
    my $self = shift;
    # Post-response shutdown functions
    # ここにはデータベースの切断を書くとよい。
}

sub start {
    my $self = shift;
    my $template = $self->load_tmpl('test.tmpl',  die_on_bad_params => 0,
        path => ['......./cgi-bin/templates'],
#      cache => 1,
#      double_cache => 1,
#      file_cache => 1,
#      file_cache_dir => '/tmp',
#      double_file_cache => 1
    );
    return &template($template);
}

sub end {
}

sub template {

    my $template = shift;

    # the fruit data - the keys are the fruit names and the values are
    # pairs of color and shape contained in anonymous arrays
    my %fruit_data = (
                    Apple  => ['Red, Green or Yellow', 'Round'      ],
                    Orange => ['Orange'              , 'Round'      ],
                    Pear   => ['Green or Red'        , 'Pear-Shaped'],
                    Banana => ['Yellow'              , 'Curved'     ],
                   );

    my @loop;  # the loop data will be put in here

    # fill in the loop, sorted by fruit name
    foreach my $name (sort keys %fruit_data) {
        # get the color and shape from the data hash
        my ($color, $shape) = @{$fruit_data{$name}};
   
        # make a new row for this fruit - the keys are <TMPL_VAR> names
        # and the values are the values to fill in the template.
        my %row = (
               name  => $name,
               color => $color,
               shape => $shape
              );

        # put this row into the loop by reference            
        push(@loop, \%row);
    }

    # call param to fill in the loop with the loop data by reference.
    $template->param(fruit_loop => \@loop);

    # print the template
    return $template->output;
}

1;

test.tmpl の内容:

<HTML>
    <HEAD>
        <TITLE>Fruity Data</TITLE>
    </HEAD>
    <BODY>

        <H1>Fruity Data</H1>

        <TABLE BORDER=1>

            <TR>
                <TD><B>Fruit Name</B></TD>
                <TD><B>Color</B></TD>
                <TD><B>Shape</B></TD>
            </TR>

        <TMPL_LOOP NAME="fruit_loop">
            <TR>
                <TD><TMPL_VAR NAME="name"></TD>
                <TD><TMPL_VAR NAME="color"></TD>
                <TD><TMPL_VAR NAME="shape"></TD>
            </TR>
        </TMPL_LOOP>

        </TABLE>

    </BODY>      
</HTML>