ランタイムタイプ:ウサギの穴の奥深く

予期しないタイプ」というメモを書き始めたとき、Erlangタイプを実行時に実行することをマスターしたようで、エリクサーのクライアントコードで使用できるようになりました。ははは、私はどれほど素朴でしたか。



リンクで提案されているものはすべて、のような明示的な使用場所タイプの定義で機能しuse Foo, var: type()ます。残念ながら、このアプローチは、別の場所でタイプを定義したい場合に運命づけられます。モジュール属性を使用するコード内のその隣、または構成内です。たとえば、構造を定義するには、次のように記述します。



# @fields [foo: 42]
# defstruct @fields

@definition var: atom()
use Foo, @definition


フランスのカタロニアの灯台



上記のコードは、型を希望どおりに処理しないということではありません@definition var: atom()例外スローされるため、まったく収集されません** (CompileError) undefined function atom/0



素朴なアプローチ



 — « » ( @tsilb, , .) , , , , — .



, , __using__/1: , ( field → type()),  — , , , {Module, :type, [params]}. ~q||, , , , AST. quote/1 : foo: ~q|atom()|. , , . . , - , , , , . , , - - - , .



. , erlang  —  , , .  — , , ( ).



, . , , , , , , —  . , .



Tyyppi



,  — , XY . , , —   — . Tyyppi.



Code.Typespec, . : . , , , . , , .  —  Tyyppi.of?/2, ,  — «»/«» , .



iex|tyyppi|1  Tyyppi.of? GenServer.on_start(), {:ok, self()}
#⇒ true
iex|tyyppi|2  Tyyppi.of? GenServer.on_start(), :ok
#⇒ false


- , Tyyppi.T. Tyyppi.of?/2 - — Tyyppi.of_type?/2.



iex|tyyppi|3  type = Tyyppi.parse(GenServer.on_start)
iex|tyyppi|4  Tyyppi.of_type? type, {:ok, self()}
#⇒ true


, , , , , . :erlang.term_to_binary/1, Config.Provider.





, : . , . , key: type(). Access, upserts. , Ecto.Changeset cast_field/1 validate/1.



, , , , ( , ).



defmodule MyStruct do
  import Kernel, except: [defstruct: 1]
  import Tyyppi.Struct, only: [defstruct: 1]

  @typedoc "The user type defined before `defstruct/1` declaration"
  @type my_type :: :ok | {:error, term()}

  @defaults foo: :default,
            bar: :erlang.list_to_pid('<0.0.0>'),
            baz: {:error, :reason}
  defstruct foo: atom(), bar: GenServer.on_start(), baz: my_type()

  def cast_foo(atom) when is_atom(atom), do: atom
  def cast_foo(binary) when is_binary(binary),
    do: String.to_atom(binary)

  def validate(%{foo: :default} = my_struct), do: {:ok, my_struct}
  def validate(%{foo: foo} = my_struct), do: {:error, {:foo, foo}
end


このライブラリの実際の価値が本番環境で何であるかはわかりませんが(うそ、私は知っています:なし)、開発中に確かに大きな助けになる可能性があり、検索を絞り込んで、Elixirの型の動的な性質に関連する奇妙なエラーを分離できます特に外部ソースを扱う場合。



すべてのライブラリコードは、いつものようにgithubで入手できます






ハッピーランタイムタイピング!




All Articles