Kuinのファイル単位のスコープを拡張しよう
Kuinにおいて、プログラムを別のソースファイルに分割した場合、他のファイルからは別のスコープとして認識されます。
別のソースファイルに定義された識別子を参照するには\ソース名@識別子
の形式でアクセスします。
ただし、スコープが分かれるので参照できるのはグローバルな識別子だけになっています。
func localFunc()
end func
+func globalFunc()
end func
func main()
do \other@localFunc() ... Error
do \other@globalFunc()
end func
では、複数のクラスからなるモジュールを作成する場合はどうなるでしょうか?
条件として、各クラスはモジュール名で参照するものとします。
例)\module@ClassA
や\module@ClassB
など
+class ClassA()
end class
+class ClassB()
end class
var classA: \module@ClassA
var classB: \module@ClassB
このように、同じ名前で参照するには、1つのソースファイルの中にすべての機能を詰め込むようになります。
しかしこれでは、機能が膨らむほどにソースコードが膨大になり、メンテナンス性が良いとは言えません。
include文
include文は、特定の名前で命名したサブソースのファイルを、自分のスコープに連結することができます。
例えば、先程のmodule.kn
を分割したい場合は、
module.class_a.kn
module.class_b.kn
という2つのサブソースを作成し、module.kn
からinclude文で連結します。
- サブソースの命名規則
module名
.サブソース名.kn
- include文の文法
include サブソース名
+class ClassA()
end class
+class ClassB()
end class
include class_a
include class_b
これで、別々のサブソースファイルに定義したクラスを、module
の名前で参照できるようになりました。
まとめ
1ファイル1クラスが正義ではありませんが、メンテナンス性やコーディング中のスクロール最小化を考えると、1つのソースファイルが膨大になる事を避けたいときがあります。
そのような時にinclude文を使うと、ストレスなく機能を実装することができるようになると思います。
また、ソースファイルを素材として1つのファイルで配布したい!って場合にも、参照方法を変更することなく集合させることができるので、作業性と配布のしやすさを両立させることもできます。
補足
Githubのissueより、くいなちゃんのコメントを引用します。
Kuinの各ソースファイルは、「モジュール」という
インスタンスがただ1つ存在するクラスのようなもの(≒シングルトン) になっています。
モジュールは、クラスのメソッドやプロパティのように、(グローバル)関数や変数を持ち、
外部に公開する部分だけを「+」でパブリックにします。
モジュールから他のモジュールを参照するときは、クラスとは違い、インスタンスがただ1つ必ず存在することを知っているため、
クラスよりは密接に、直接モジュール間でやりとり(関数呼び出し等)ができます。
Kuinではこのように、モジュール単位でプログラムを設計し、
インスタンスが複数になるものや、より疎結合にしたいものだけをクラスで実現するように想定しています。
クラスとモジュールの設計思想を理解し、きれいに使い分けるのが理想ですね。