عندما بدأت في كتابة الملاحظة " الأنواع التي لم تكن متوقعة " ، بدا لي أنني أتقنت إحضار أنواع Erlang إلى وقت التشغيل والآن يمكنني استخدامها في رمز العميل على الإكسير. هاها ، كم كنت ساذجة.
أي شيء يقترحه الرابط سيعمل مع تعريفات صريحة لنوع مكان الاستخدام مثل use Foo, var: type(). لسوء الحظ ، فإن هذا النهج محكوم عليه بالفشل إذا أردنا تحديد الأنواع في مكان آخر: بجانبها في الكود باستخدام سمات الوحدة ، أو هناك ، في ملف config. على سبيل المثال ، لتحديد بنية ، قد نرغب في كتابة شيء مثل هذا:
# @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
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
ليس لدي أي فكرة عن القيمة العملية لهذه المكتبة في الإنتاج (كذبة ، أعرف: لا شيء) ، لكنها بالتأكيد يمكن أن تكون مساعدة كبيرة أثناء التطوير ، مما يسمح لك بتضييق نطاق البحث وعزل الأخطاء الغريبة المتعلقة بالطبيعة الديناميكية للأنواع في الإكسير خاصة عند التعامل مع مصادر خارجية.
كل كود المكتبة متاح ، كالعادة ، على جيثب .
وقت تشغيل سعيد الكتابة!