[perl] Perl でクラス変数を作る方法
続・初めてのPerl を読んでいて少し混乱したので、クラス変数の作り方をメモしておく。
結論から言うと、Perl でクラス変数を作るには「our演算子」を使う。ラクダ本 p.156 によると、our変数は、
ourは値を生成するのではなく、グローバル変数(これは永遠に存在する)に対して、制限された形でのアクセスを提供するもの
とある。これをラクダ本の言葉を借りて一言で言い直すと、「ourはレキシカルスコープを持つグローバル変数」である。
今のところ、自分の理解している範囲での our は以下のような感じ。
スコープ:レキシカル
命:グローバルなのでメモリ中に1つしか存在しない
ということは、クラス変数としてピッタリだよねっていう話。
以下にクラス変数を作る際の our の使い方を示したサンプルコードを載せておく。
#!/usr/bin/perl use strict; use warnings; { package Animal; use Carp qw(croak); use Scalar::Util qw(weaken); sub speak { my $class = shift; print $class->name, ' goes ', $class->sound, "!\n"; } sub name { my $either = shift; ref $either or croak "instance variable needed"; $either->{Name}; } # %REGISTRY はクラス変数 our %REGISTRY; sub named { ref(my $class = shift) and croak 'class only'; my $name = shift; my $self = { Name => $name, Color => $class->default_color }; bless $self, $class; $REGISTRY{$self} = $self; weaken($REGISTRY{$self}); $self; } sub registered { return map { 'a ' . ref($_) . " named " . $_->name } values %REGISTRY; } sub DESTROY { my $self = shift; print '[', $self->name, " has died.]\n"; } } { package Horse; use base qw{Animal}; sub sound { 'neigh' } sub default_color { 'white' } sub DESTROY { my $self = shift; $self->SUPER::DESTROY; print "[", $self->name, " has gone off to the glue factory.]\n"; } } my $horse = Horse->named('Mr. Ed'); print "We've seen:\n", map " $_\n", $horse->registered;