1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Perl:Tied Variablesによる変数の拡張

Last updated at Posted at 2025-12-06

はじめに

Perlの備忘録として書いてます。
前回はシンボルテーブルについて記載しました。今回は、変数の挙動をカスタマイズする tie について。

tie とは

Perlの変数は、通常は単なるデータの入れ物です。しかし、tie 関数を使うと、変数を特定のクラス(そのクラスのオブジェクト)に結びつけることができます。

これにより、変数へのアクセス(読み込み、書き込み、キーの確認など)を、特定のメソッド呼び出しにフックさせることが可能になります。「変数に見えるけれど、裏側でAPIを叩いている」といった実装も可能です。

実践:スカラー変数の拡張

最も単純なスカラー変数の tie を見てみましょう。
値を代入すると、その内容を標準出力にログとして表示する変数を作成します。

package LoggingScalar;

sub TIESCALAR {
    my ($class, $value) = @_;
    # 第2引数があれば初期値として利用する
    return bless \$value, $class;
}

sub FETCH {
    my $self = shift;
    return $$self;
}

sub STORE {
    my ($self, $value) = @_;
    print "[LOG]: $value\n";
    $$self = $value;
}

package main;

# 変数 $log_var を LoggingScalar クラスに紐付ける
tie my $log_var, 'LoggingScalar', "initial_value";

print $log_var . "\n"; # initial_value
$log_var = "hello";    # 出力: [LOG]: hello
print $log_var;        # hello
  • TIESCALAR: tie 時に呼ばれるコンストラクタ
  • FETCH: 変数の値を読み取る時に呼ばれる
  • STORE: 変数に値を代入する時に呼ばれる

これを利用すれば、代入するだけでファイルに永続化される変数や、常に現在時刻を返す変数などを作成できます。

実践:ハッシュ変数の拡張(継承の活用)

ハッシュや配列を tie する場合、すべてのメソッド(STORE, DELETE, EXISTS, FIRSTKEY...)を実装するのは大変です。

そこで、Tie::StdHash モジュールを継承します。これにより、挙動を変えたいメソッドだけをオーバーライドすればよくなり、実装コストが下がります。

ここでは、「存在しないキーにアクセスすると、自動的にデフォルト値を生成して保存する」ハッシュを作成してみます。

package AutovivifyHash;
require Tie::Hash;
# Tie::StdHash を継承することで、FETCH 以外のメソッドの実装を省略できる
@ISA = qw(Tie::StdHash);

sub FETCH {
    my ($self, $key) = @_;
    # 親クラスのメソッドを使って存在確認
    unless (exists $self->{$key}) {
        print "Generating default value for $key...\n";
        $self->{$key} = "default";
    }
    return $self->{$key};
}

package main;

tie my %hash, 'AutovivifyHash';

print $hash{foo}; 
# 出力:
# Generating default value for foo...
# default

# 代入などの通常の操作は親クラス(Tie::StdHash)が処理してくれる
$hash{bar} = 123; 
print $hash{bar}; # 123

補足:オブジェクトの取得と untie

tie は、裏側で生成されたオブジェクトを戻り値として返します。
また、紐付けを解除したい場合は untie を使用します。

# オブジェクトを受け取る
my $obj = tie my $scalar, 'LoggingScalar';

# $obj を通じて裏側のメソッドを直接呼ぶことも可能
# $obj->some_method();

# 紐付けを解除(通常の変数に戻る)
untie $scalar;

応用例

tie は、モジュール利用者に「直感的なインターフェース」を提供するために使われています。

  • DBMファイル: ディスク上のファイルをハッシュのように扱う(DB_File, GDBM_Fileなど)
  • Configファイル: 設定ファイルを読み込んでハッシュとして見せる
  • プロセス間通信: 共有メモリを変数として見せる(IPC::Shareable

まとめ

  • tie を使うと、変数の操作をメソッド呼び出しに変換できる
  • Tie::StdHash などを継承すると、必要な機能だけをカスタマイズできて便利
  • スカラー、ハッシュだけでなく、配列(Tie::Array)やファイルハンドル(Tie::Handle)も作成可能
  • 便利だが、通常の変数に比べてメソッド呼び出しのオーバーヘッドがあるため、パフォーマンスは注意

参考:https://perldoc.jp/

次回は、Perlの「ソースフィルタ」について記載します。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?