Elixirの色々なパッケージのコードを見ていると、下記のような@specディレクティブが頻繁に登場します。
@spec foo(Bar.t | t) :: t
(@specディレクティブに関してはこちらをご参照ください)
「この"t"ってなんだよ?」と思ったことはありませんでしょうか?
"t"について
ということで調べてみましたが、結論から言うと上記の"t"は、それぞれのモジュールで
@type t :: 色々な型定義
のような感じで定義されています。多くの場合は
@type t :: %__MODULE__{〜構造体のフィールドの型定義を羅列〜}
のような感じで、そのモジュール内でdefstructで定義している(%モジュール名
で参照できる)構造体の型情報を返す目的で使用されているようです。
"remote type"について
Elixirのtypespecsに関するドキュメントの途中に、「remote types」という用語が突然登場します。
この「remote type」とは一体なんだろう?ということで調べてみたのですが、これはerlang用語のようです。こちらで説明されています。
要するに、あるモジュールからexportされて、他のモジュールで参照可能な型定義のことを「remote type」と呼ぶようです。
まとめ
Elixirの場合、@type
で外部にエクスポートする、そのモジュールの型情報を「t」という名称で定義することが慣例のようなので、「remote type」とは要するに@type t :: 色々な型定義
という形式で定義された、Hoge.t
のような構文で参照可能なそのモジュールの構造体情報のこと、と考えて良いと思われます。
補足
Elixirの型定義ディレクティブには、@type
以外にも@typep
および@opaque
が使用可能です。こちらでそれぞれ下記のように説明されています。
A type defined with @typep is private. An opaque type, defined with @opaque is a type where the internal structure of the type will not be visible, but the type is still public.
@typep
で定義された型はプライベートになりますので他のモジュールからは参照できません。そのため@typep
で定義された型は「remote type」とは呼ばないと思われます。
@opaque
で定義された型は、他のモジュールから参照可能ですが、その内部構造は隠蔽されているため、他のモジュールがその型の内部構造にアクセスするようなコードは不可ということになるようです。(おそらくdialyzer等の静的型チェックツールでチェックするとエラーになるのではないかと思われます)