FileHandle に書き込んでいたデータの出力先を変数にしてくれるIO::Scalar

By admin | 2009年5月1日

タイトルの通り今回したかったのはファイルハンドルを使って
ファイルへ出力していたコードの出力先を変数にしたかった。

そういうことをしてくれる小粋なモジュール IO::Scalar を使って対応しました。
これがまた便利で、数行書き換えるだけでよくてパフォーマンスは使う前と後で、それほど差異はありませんでした。

通常の FileHandle を使ったコード

#!/usr/bin/perl

use strict;
use warnings;

open my $fh, '>', 'file' or die $!
print $fh 'hoge'; #この時点で file とう名前のファイルがカレントディレクトリにつくられます。

1;

IO::Scalar を使って出力先を変数にしたコード

#!/usr/bin/perl

use strict;
use warnings;
use IO::Scalar;

my $file;
my $out;
{
    my $fh = IO::Scalar->new(\$out);
    local *F = $fh;
    $file = *F;
    print $file "hoge\n";
}
warn $out;

1;

で、調べていくと IO::String というモジュールも同じようなことをしてくれることを知った。
ちょっと試してみたけどインターフェースはさほどかわりない感じ。
というわけでベンチ。

           Rate IO_STRING IO_SCALAR
IO_STRING 210/s        --      -44%
IO_SCALAR 373/s       77%        --

見た通り IO::Scalar の方がはやいですね。
試したコードはこれ。

#!/usr/bin/perl

use strict;
use warnings;

use IO::String;
use IO::Scalar;
use Benchmark qw/cmpthese/;

my @data = map { int rand 1000 } 1..1000;

cmpthese(10000, {
        IO_STRING => \&with_io_string,
        IO_SCALAR => \&with_io_scalar,
});

sub with_io_scalar {
    my $output;
    my $ios = IO::Scalar->new(\$output);
    local *STDOUT = $ios;
    print $_ for @data;

#    warn $output;
}

sub with_io_string {
    my $output;
    my $ios = IO::String->new(\$output);
    local *STDOUT = $ios;
    print $_ for @data;

#    warn $output;
}

1;

参考資料

IO::Scalarで色々
IO::scalarでIOのキャプチャ

コメントはまだありません

コメントはまだありません。

このコメント欄の RSS フィード TrackBack URI

コメントをどうぞ

WordPress Themes