こんにちは、Perl 6アドベントカレンダーの13日目の投稿になります。
今回はちょっとしたTipsとして循環参照でこまってしまったときの解決方法を紹介しようと思います。
イントロ
準備
下記のようなディレクトリ構成、内容のファイルを生成してみましょう。
tree
$ tree
.
├── cycle.p6
└── lib
├── A.pm6
└── B.pm6
cycle.p6
use lib 'lib';
use A;
A.pm6
use B;
class A { has B $!b; submethod BUILD { } };
B.pm6
use A;
class B { has A $!a; submethod BUILD { } };
エラー
実行してみると下記のようなエラーが出てしまうはずです。
これはクラスAとクラスBが循環参照の状態になっているためです。
実行
$ perl6 cycle.p6
===SORRY!===
Circular module loading detected trying to precompile /home/itoyota/Programs/cycle/lib/A.pm6
というわけで、この循環参照によるエラーを避けるために、ちょっとした工夫が必要になります。
解決策
下記のような方法で解決できます:
- クラスAとクラスBを1つにまとめたAB.pm6を作る。
- クラスAの定義の前に、クラスBのスタブを呼び出す
tree
$ tree
.
├── ok-cycle.p6
└── lib
└── AB.pm6
AB.pm6
class B { ... }
class A { has B $!b; submethod BUILD { } };
class B { has A $!a; submethod BUILD { } };
ok-cycle.p6
use lib 'lib';
use AB;
dd A.new;
dd B.new;
実行
$ perl6 ok-cycle.p6
A.new
B.new
うまく実行できました。
以上、Perl 6アドベントカレンダーの13日目の投稿で、Perl 6で循環参照で困ったときの解決方法でした。
参考
- 今日のTipsは、実は昔ircで私が質問して、開発メンバーの方からもらった回答です