home Glamenv-Septzen(ぐらめぬ・ぜぷつぇん)(archive)

Perl/codepiece/pseudo_block

作成日: 2007-02-21 22:58:30   /   last updated at: 2008-12-24 22:59:25
カテゴリ: Perl 

  • "{", "}"は、パッケージ・ブロック・ハッシュコンストラクタの三つの顔を持ち、それぞれは使用されている箇所でのコンテキストにより切り替わる。
  • ここでは、無名関数として使用されるシーンを活用し、ユーザー定義の疑似ブロックのサンプルを掲示する。
  • <= Perl 5.8
  • pseudo_block1.pl
#!/usr/bin/perl
use strict;
use warnings;
use IO::File;

sub pseudo_block(&$) {
	my ($block, $fname) = @_;
	my $fh = new IO::File;
	if ($fh->open("<$fname")) {
		$block->($fh);
		$fh->close;
	} else {
		die "$fname open failed.\n";
	}
}

pseudo_block {
	my ($fh) = @_;
	print <$fh>;
} "test.dat";
  • test.dat : 適当なテキストファイル
ab
cd
efg
  • 出力:ファイルがあるとき
>perl pseudo_block1.pl
ab
cd
efg
  • 出力:ファイルが無いとき
>perl pseudo_block1.pl
test.dat open failed.

美しさから言えば、"test.dat"にあたるプロトタイプの順番を逆にして以下のようにしたいところだが、"{" "}"がハッシュコンストラクタとして解釈されてしまうらしく、syntax errorになってしまう。

sub pseudo_block($&) {
my ($fname, $block) = @_;
...
}

pseudo_block "test.dat", {
        my ($fh) = @_;
        ...
} 

このように、トランザクション的な処理をカプセル化したい場合、強力なツールとして使用できる。誰でも簡単に思いつくのは、以下のような例ではないだろうか。

sub transact(&$) {
    my ($block, $dbh) = @_;
    try {
        $block->($dbh);
        $dbh->commit;
    } catch {
        $dbh->rollback;
    }
}

transact {
    my ($dbh) = @_;
    $dbh->do("(some sql)");
} $dbh;

original url: https://www.glamenv-septzen.net/view/119