App::Hacheroのテストで、

use File::Temp;
use IO::All;

my $out = File::Temp->new->filename;
local *STDOUT;
open STDOUT, '>', $out;
....
close STOUT;
my $contents < io $out;
is $contents, 'hoge';

というような感じのテストを書いていて、全然普通に使えてたんだけど、/tmp以下にもりもりテンポラリファイルがたまっていっててちょう嫌な感じだったんで、↓こんな感じでちゃんと消えるようにした。

my $fh = File::Temp->new;
close $fh;
my $out = $fh->filename;

っていうかファイル名だけ欲しいんだけどー、という時にどうやればいいんかな。

*追記 id:lestrrat師匠から

File::Temp->new(UNLINK => 1) じゃだめ? 返ってきた実体は文字列として扱うとファイル名になるよ « ってご指摘いただいたんですが、↓こんな感じで書くと

#!/usr/bin/perl

use strict;
use warnings;
use Test::More tests => 1;
use File::Temp;
use IO::All;

my $expect = 'hogehoge';
my $out =  File::Temp->new;
diag $out;
open my $fh, '>', $out;
print $fh $expect;
close $fh;

my $contents < io $out;
is $contents, $expect;

まあこの場合普通にFile::Tempからかえってくるfhを使えばいいんですけど。diagの所ではちゃんとファイル名がかえってきてるんだけど、

[danjou@guido] $ perl test.pl
1..1
# /tmp/YK07aYW9e6

Can't call method "opened" on an undefined value at /usr/lib/perl5/site_perl/5.8.8/IO/All/File.pm line 82.
# Looks like your test died before it could output anything.

などと言われる。ちなみに↓こっちだとやっぱり問題ない。

#!/usr/bin/perl

use strict;
use warnings;
use Test::More tests => 1;
use File::Temp;
use IO::All;

my $expect = 'hogehoge';
my $fh =  File::Temp->new;
print $fh $expect;
close $fh;

my $contents < io $fh->filename;
is $contents, $expect;

*さらにつづき 師匠からさらに。http://mt.endeworks.jp/d-6/2008/09/filetemp.html

#!/usr/bin/perl

use strict;
use warnings;
use Test::More tests => 1;
use File::Temp;
use IO::All;

my $expect = 'hogehoge';
my $tmp =  File::Temp->new;
print $tmp $expect;
close $tmp;

my $contents < io "$tmp";
is $contents, $expect;

ということでなるほどこれはいけますね。 あれ?いやいや、ここでしたかったことは、

open *STDOUT, '>', $tmpfilename;

ということだったので、STDOUTとFile::Tempで作ったテンポラリファイルを結びつけたかった訳です。なんか問題がややこしくなってきました。