Size: a a a

Эликсир и Вунш

2020 February 07

LL

Lama Lover in Эликсир и Вунш
Artem Denezhny
#FunBox #json #elixir

Наконец-то #FunBox начали нам выдавать что-то кроме своих вакансий с космическими требованиями))

посмотрим, покритикуем, мяч теперь на нашей стороне))

https://github.com/savonarola/edantic
Бесполезная тема, которая резолвит тайпспеки в рантайме. Такая валидация работает супердолго
источник

МК

Максим Кузьмин in Эликсир и Вунш
Lama Lover
Бесполезная тема, которая резолвит тайпспеки в рантайме. Такая валидация работает супердолго
Ну, иногда скорость в кмч - не самое важное в гоночной машине
источник

МК

Максим Кузьмин in Эликсир и Вунш
Так то выглядит достаточно удобненько
источник

МК

Максим Кузьмин in Эликсир и Вунш
Но пробовать конечно надо
источник

LL

Lama Lover in Эликсир и Вунш
Максим Кузьмин
Так то выглядит достаточно удобненько
Я скажу, что этот подход не будет работать по двум причинам
1. Это ну очень долго - лазеть в бинарное представление модуля за тайпспеками, парсить тайпспеки, генерить замыкания
2. Функционал обрезан, потому что очень часто требуется гораздо больше преобразований и валидаций, чем можно написать в тайпспеке
источник

SM

Sergei Maximov in Эликсир и Вунш
Since type info is located in seperate beam chunks which are stripped by default, be sure your releases do not strip them. 😕
источник

SM

Sergei Maximov in Эликсир и Вунш
Вот дельное предложение
источник

LL

Lama Lover in Эликсир и Вунш
Это мой issue 😏
источник

LL

Lama Lover in Эликсир и Вунш
Но там проблема,
Code.Typespec.fetch_types, которым пользуются в edantic не позволяет тянуть тайпспеки модуля, который ещё не скомпилирован
источник

SM

Sergei Maximov in Эликсир и Вунш
Lama Lover
Но там проблема,
Code.Typespec.fetch_types, которым пользуются в edantic не позволяет тянуть тайпспеки модуля, который ещё не скомпилирован
А если компилировать во внешний модуль?

Типа так


Edantic.define_cast_module(MyModule.Cast, for: MyModule)
источник

АЮ

Андрей Юнми in Эликсир и Вунш
Ecto.Changeset выглядит удобнее.
источник
2020 February 08

AD

Artem Denezhny in Эликсир и Вунш
@LamaLove спасибо
источник

SM

Sergei Maximov in Эликсир и Вунш
Lama Lover
Но там проблема,
Code.Typespec.fetch_types, которым пользуются в edantic не позволяет тянуть тайпспеки модуля, который ещё не скомпилирован
Можно, кстати, через Module.get_attribute(:type | :typep | :opaque, []) внутри @before_compile-хука получить список всех типов, определённых внутри компилируемого модуля. А для remote-типов рекурсивно уже вызывать Code.Typespec.fetch_types внутри этого же хука.

Тут единственная проблема в том, что Module.get_attribute возвращает AST определения типа, которое отличается от представления, которое возвращает Code.Typespec.fetch_types (но это представление можно обратно сконвертировать в AST с помощью Code.Typespec.type_to_quoted).
источник

LL

Lama Lover in Эликсир и Вунш
Sergei Maximov
Можно, кстати, через Module.get_attribute(:type | :typep | :opaque, []) внутри @before_compile-хука получить список всех типов, определённых внутри компилируемого модуля. А для remote-типов рекурсивно уже вызывать Code.Typespec.fetch_types внутри этого же хука.

Тут единственная проблема в том, что Module.get_attribute возвращает AST определения типа, которое отличается от представления, которое возвращает Code.Typespec.fetch_types (но это представление можно обратно сконвертировать в AST с помощью Code.Typespec.type_to_quoted).
Да, но Module.get_attribute не будет работать когда ты компилируешь один модуль из своего проекта, который использует тип другого модуля
Code.Typespec.fetch_types тоже не будет работать (я проверял)
источник

LL

Lama Lover in Эликсир и Вунш
Я, кстати, сделал либу которая превращает тайпспеки с валидирующие функции как раз через @before_compile. Она делает валидаторы в компайле и напрямую из ast, но у неё есть пара неровностей.  И она, скорее всего, не выйдет в открытый доступ, потому что я делал её в рабочее время
источник

SM

Sergei Maximov in Эликсир и Вунш
Lama Lover
Да, но Module.get_attribute не будет работать когда ты компилируешь один модуль из своего проекта, который использует тип другого модуля
Code.Typespec.fetch_types тоже не будет работать (я проверял)
А для remote-типов рекурсивно уже вызывать Code.Typespec.fetch_types внутри этого же хука.
источник

LL

Lama Lover in Эликсир и Вунш
Sergei Maximov
А для remote-типов рекурсивно уже вызывать Code.Typespec.fetch_types внутри этого же хука.
Сейчас покажу контрпример
источник

LL

Lama Lover in Эликсир и Вунш
Sergei Maximov
А для remote-типов рекурсивно уже вызывать Code.Typespec.fetch_types внутри этого же хука.
defmodule Playground do
 @type t :: integer()
end

defmodule Playground.Macro do
 defmacro m({{:".", _, [module, _type] }, _, []}) do
   module = Macro.expand(module, __CALLER__)
   IO.inspect Code.Typespec.fetch_types(module), label: :here
 end
end

defmodule Playground2 do
 require Playground.Macro

 def f() do
   Playground.Macro.m(Playground.t())
 end

end


Выведет here: :error при компиляции
источник

M

Marperia in Эликсир и Вунш
Lama Lover
Я, кстати, сделал либу которая превращает тайпспеки с валидирующие функции как раз через @before_compile. Она делает валидаторы в компайле и напрямую из ast, но у неё есть пара неровностей.  И она, скорее всего, не выйдет в открытый доступ, потому что я делал её в рабочее время
Как вариант — кинуть коммьюнити основные куски кода, пусть дальше сами разбираются

Но это если кому-то нужно будет, я вот свой синтаксический транслятор закончить не могу уже пол года, так что...)
источник

SM

Sergei Maximov in Эликсир и Вунш
Lama Lover
defmodule Playground do
 @type t :: integer()
end

defmodule Playground.Macro do
 defmacro m({{:".", _, [module, _type] }, _, []}) do
   module = Macro.expand(module, __CALLER__)
   IO.inspect Code.Typespec.fetch_types(module), label: :here
 end
end

defmodule Playground2 do
 require Playground.Macro

 def f() do
   Playground.Macro.m(Playground.t())
 end

end


Выведет here: :error при компиляции
Пичаль
источник