読者です 読者をやめる 読者になる 読者になる

量産型エンジニアの憂鬱

きっと僕は何物にもなれない。

Perl6のコンストラクタと継承

Perl5にはクラス構文がありません。

モジュール名で bless された リファレンスをインスタンスとして扱うことができます。
ハッシュリファレンスまたは無名ハッシュを bless した場合、キー値ペアをメンバとして使えます。
Perl5 では new メソッドで 自身のモジュール名で bless した 無名ハッシュ を返すことでコンストラクタとして利用しています。

また、グローバル変数 @ISA にスーパークラスを指定することで、スーパークラスのメソッドが利用できるようになります(継承)。
上記スクリプト内では Bird インスタンスが Animal の name メソッドを利用しています。


さて、Perl6ではクラス構文が存在しています。

is で継承することができます。自然言語っぽくていいですね。 Bird is Animal。
メンバ変数が public な場合は上記のように簡単に記述することができます。
継承してもデフォルトコンストラクタがよしなにやってくれています。

メンバを private 変数にした場合はどうなるでしょうか。

全て Nil になってしまいました。
前回 の記事で書いた通り、 デフォルトコンストラクタでは private なメンバに値を渡してくれないようです。

今回は、継承した場合のコンストラクタについて考えましょう。

method new はオーバーライドされてしまう

サブクラスの new がスーパークラスの new でオーバーライドしてしまいます。

サブクラスで new メソッドを定義した場合に、スーパークラスの new が呼ばれず、値が設定できません。
また、サブクラスからスーパークラスの private メンバにアクセスすることもできません。
前回の記事のように無理やり private なメンバに値を設定してやろうとしていると、継承したときにスーパークラスの値が設定できなくなってしまいます。

submethod BUILDを使う

submethod BUILD の場合、スーパークラスのコンストラクタも呼ばれます。

スーパークラスの private メンバにも値を設定してやることができます。

method new と bless で書く方が Perl5 での記述と似ていてついそっちで書きたくなってしまうのですが、
基本 submethod BUILD 使う方がいいですね。