Как эффективно перезагрузить структуры?

Я нашел минимальный пример, который показывает одну из проблем, с которыми я сталкиваюсь при изучении эликсира.

Я пишу сценарий:

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
Другие вопросы по тегам