Perl/class
クラス 編集
Perl5.36までは、bless
を使ったパッケージベースのオブジェクト指向が採用されていました。
Perl5.38からは、新たにキーワードclass
が導入され、より一般的なクラスベースのオブジェクト指向言語のスタイルでコードを書けるようになりました。
また、class
構文はbless
の糖衣構文ではなく、新たなオブジェクト機構を提供しています。
classの宣言と利用 編集
use v5.38; use feature 'class'; no warnings 'experimental::class'; class Hello { field $name :param; method say_hello { say "Hello, $name!"; } } my $hello = Hello->new(name => "Universe"); $hello->say_hello;
- 実行結果
Hello, Universe!
- このコードは、Perl 5.38を使用してクラスを使った"Hello, World!"の例です。
- まず、
use v5.38;
はPerlのバージョンを5.38に指定しています。次に、use feature 'class';
は、Perl 5.0から実験的に導入されたクラス機能を有効にしています。さらに、no warnings 'experimental::class';
は、クラス機能に関する実験的な警告を無効にしています。 class Hello { ... }
のブロックで、Hello
という名前のクラスを定義しています。field $name :param;
は、クラスのフィールドである$name
を定義しています。:param
は、$name
がコンストラクタの引数であることを示しています。method say_hello { ... }
のブロックで、say_hello
というメソッドを定義しています。say "Hello, $name!";
は、"Hello, $name!"というメッセージを表示しています。$name
はフィールドの値を参照しています。my $hello = Hello->new(name => "Universe");
では、Hello
クラスのインスタンスを作成しています。コンストラクタには、name
というキーワード引数とその値が渡されています。- 最後の行の
$hello->say_hello;
では、$hello
インスタンスのsay_hello
メソッドを呼び出しています。この結果、"Hello, Universe!"という出力が得られます。
- packeageとblessを使った等価な実装例
use v5.30; use feature 'signatures'; no warnings "experimental::signatures"; package Hello { sub new: prototype($$)($class, $name) { bless { name => $name, }, $class; } sub say_hello($self) { say "Hello, @{[ $self->{name} ]}!" } } my $hello = Hello->new("Universe"); $hello->say_hello;
- 実行結果
Hello, Universe!
- このコードは、Perl 5.30を使用してオブジェクト指向を使った"Hello, World!"の例です。
- 最初に、
use v5.30;
を使用してPerlのバージョンを5.30に指定しています。次に、use feature 'signatures';
は、サブルーチンに引数の型指定を行うための機能を有効にしています。さらに、no warnings "experimental::signatures";
は、引数の型指定に関する実験的な警告を無効にしています。 package Hello { ... }
のブロックで、Hello
という名前のパッケージ(クラス)を定義しています。sub new: prototype($$)($class, $name) { ... }
は、new
というサブルーチン(コンストラクタ)を定義しています。prototype($$)
は、引数の型指定を行っています。$class
と$name
はそれぞれクラス名と名前の引数を表しています。bless
関数を使用して、name
フィールドを持つハッシュリファレンスを作成し、それをクラスに対してブレス(関連付け)しています。sub say_hello($self) { ... }
は、say_hello
というサブルーチン(メソッド)を定義しています。$self
は、メソッドが呼び出されるインスタンス自体を表します。$self->{name}
を参照して、"Hello, $self->{name}!"というメッセージを表示しています。my $hello = Hello->new("Universe");
では、Hello
クラスのインスタンスを作成しています。引数として"Universe"が渡されます。- 最後の行の
$hello->say_hello;
では、$hello
インスタンスのsay_hello
メソッドを呼び出しています。この結果、"Hello, Universe!"という出力が得られます。
- 小まとめ
- パッケージ宣言とは異なり、クラス宣言では
class
というキーワードを使用します。 - クラス宣言はブロック構文または文構文のいずれかで行うことができます。
- クラス宣言内で、
field
というキーワードを使用してフィールド(クラスのインスタンス変数)を宣言できます。フィールドはクラスのスコープ内でのみ参照可能であり、各インスタンスごとに独自のフィールドの値を持ちます。 - クラス宣言内で、
method
というキーワードを使用してメソッド(クラスのサブルーチン)を宣言できます。メソッドはクラスのインスタンス内で呼び出されることを意図しており、自動的に特殊変数$self
が生成され、メソッド内で使用されます。 - クラスやフィールドには属性を指定することができます。例えば、クラスの継承を指定する
:isa
属性や、フィールドの初期化を制御する:param
属性があります。
- これらの機能を使用することで、Perlにおいてよりオブジェクト指向プログラミングのパラダイムに則ったコーディングが行えるようになります。
- ただし、この機能は実験的なものであり、将来のバージョンで変更されたり、削除されたりする可能性があります。最新のリリースノートや公式ドキュメントを参照することをおすすめします。
特殊コードブロック 編集
ADJUST 編集
ADJUSTブロックは、Perlのクラス構文で使用される特殊なブロックです。このブロックはクラスの宣言内で定義され、オブジェクトの構築中に実行されるカスタムコードを含めるために使用されます。 ADJUSTブロックは、クラスのフィールド(インスタンス変数)やメソッドが初期化される前に実行されます。つまり、オブジェクトが構築される過程でフィールドの値を調整するために使用されます。
以下にADJUSTブロックの基本的な構文を示します:
class MyClass { field $field1; field $field2; ADJUST { # フィールドの値を調整するカスタムコード } method my_method { # メソッドの実装 } }
ADJUSTブロックは、クラス内でフィールドの初期値を設定したり、関連するフィールドの相互作用を制御したりするために使用されます。例えば、複数のフィールドの初期値に基づいて他のフィールドを計算する場合に便利です。 ADJUSTブロック内では、特殊変数「$self」を介して現在のオブジェクトインスタンスにアクセスすることができます。また、ADJUSTブロック内で定義された変数は、そのブロック内でのみ有効です。 ADJUSTブロックは、クラスの宣言内で複数回定義することができます。その場合、定義された順序に従って順番に実行されます。 なお、ADJUSTブロックはPerl 5.38.0から導入された実験的な機能であり、将来のバージョンで変更される可能性があります。最新のリリースノートや公式ドキュメントを確認することをおすすめします。
class構文で実装予定でv5.38では未実装な機能 |
class構文はまだ実験的であり、非常に不完全です。以下のリストは、追加や変更が必要な作業の一部の概要を示しています。
|
プラグマ 編集
use feature 'class';
warnings 編集
no warnings 'experimental::class';