日向夏特殊応援部隊

俺様向けメモ

一時ファイルの作成とpackage別の一時ディレクトリ

CatalystではrequestデータのparseにHTML-Bodyを使っています。

で良くご存じの通り、Uploadされたファイルに関しては、勝手にテンポラリファイルとしてテンポラリディレクトリに保存される次第です。

このテンポラリなディレクトリはLinuxとかならば/tmpでいいんですが、ファイル名は果してどういう風に付けているかと言えば、File-Tempと言うモジュールが存在していました。

File::TempのOOインターフェース

http://search.cpan.org/dist/File-Temp/Temp.pm#OBJECT-ORIENTED_INTERFACE

まぁ、こちらにある通りなんですけど、

  1. TEMPLATE
  2. DIR
  3. SUFFIX

ってのが指定出来ます。TEMPLATEは面白い機能で、XXXってのを指定するとその部分がランダム文字列に置き換わる仕様になってます。

#!/usr/bin/perl

use strict;
use warnings;

use File::Temp;

my $tmpfile = File::Temp->new(TEMPLATE => 'zigorou_XXXXXX');
print $tmpfile->filename;

みたいな感じで書いたら、

$ perl tempfile.pl
/tmp/zigorou_YfWfia

って保存されます。

Catalyst::Utils::class2tempdir()

Catalystを使う上である程度熟知しておくべきモジュールの一つであるCatalyst::Utilsですが、「モジュール化」の為に色々と便利な機能を提供してくれています。
その一つがclass2tempdir()関数だと思います。

class2tempdir( $class [, $create ] );
Returns a tempdir for a class. If create is true it will try to create the path.

と言う次第なので、$createを1としてやるとそのディレクトリが無い場合は作ってくれます。

実装見てみましょう。

sub class2tempdir {
    my $class  = shift || '';
    my $create = shift || 0;
    my @parts = split '::', lc $class;

    my $tmpdir = dir( File::Spec->tmpdir, @parts )->cleanup;

    if ( $create && !-e $tmpdir ) {

        eval { $tmpdir->mkpath };

        if ($@) {
            Catalyst::Exception->throw(
                message => qq/Couldn't create tmpdir '$tmpdir', "$@"/ );
        }
    }

    return $tmpdir->stringify;
}

ってかClass::Path、凄い便利すねぇ。それは置いといて、package階層をlcしてdir階層にしてくれるので、モジュールごとにかち合わないtmpdirを作成することが出来ます。

Catalyst内でモジュール別のテンポラリファイルを作成する

上記を踏まえてこんな感じになります。

#!/usr/bin/perl
package Catalyst::Plugin::Boofy;

use strict;
use warnings;

use Catalyst::Utils;
use File::Temp;

my $tmpfile = File::Temp->new(
    DIR => Catalyst::Utils::class2tempdir(__PACKAGE__, 1),
    TEMPLATE => 'mixi_XXXXXXXX'
);

print $tmpfile->filename;

で結果。

$ perl tempfile.pl
/tmp/catalyst/plugin/boofy/mixi_mKylzEFT

I love Boofyって事で。