Как эффективно перезагрузить структуры?
Я нашел минимальный пример, который показывает одну из проблем, с которыми я сталкиваюсь при изучении эликсира.
Я пишу сценарий:
defmodule P do
defstruct a: 2
def geta(%P{a: a}), do: a
end
использование iex "filename"
начать iex
проверьте сессию, что это работает с P.geta(%P{a: 42})
Затем я изменяю файл на
defmodule P do
defstruct a: 2, b: 4
def getb(%P{a: a, b: b}), do: b
end
И когда я запускаю iex
не получается:
== Compilation error on file p.ex ==
** (CompileError) p.ex:3: unknown key :b for struct P
(elixir) src/elixir_map.erl:185: :elixir_map."-assert_struct_keys/5-lc$^0/1-0-"/5
(elixir) src/elixir_map.erl:62: :elixir_map.translate_struct/4
(stdlib) lists.erl:1353: :lists.mapfoldl/3
** (exit) shutdown: 1
(elixir) lib/kernel/parallel_compiler.ex:202: Kernel.ParallelCompiler.handle_failure/5
(elixir) lib/kernel/parallel_compiler.ex:185: Kernel.ParallelCompiler.wait_for_messages/8
(elixir) lib/kernel/parallel_compiler.ex:55: Kernel.ParallelCompiler.spawn_compilers/3
(iex) lib/iex/helpers.ex:168: IEx.Helpers.c/2
Я могу обойти это, удалив содержимое файла, кроме определения, запустив iex, вставив обратно содержимое файла и перезапустив iex. Мне кажется, что старая структура как-то кешируется iex.
Два вопроса:
- Это ошибка или дизайнерское решение?
- Есть ли более умный способ обойти это?
1 ответ
Решение
Основная проблема в том, что у вас есть функции в вашем структурном модуле. Это вызовет такие проблемы, как ваше зрение. Вы должны разделить свою структуру и функции. Вы можете вложить модуль struct в свой модуль, если хотите.
defmodule P do
defmodule Data do
defstruct a: 2, b: 4
end
def geta(%Data{a: a}), do: a
def getb(%Data{b: b}), do: b
end
в iex:
iex> P.geta(%P.Data{a: 10})
10
iex> P.getb(%P.Data{a: 3, b: 24})
24