【问题标题】:iex, how to reload structs effectively?iex,如何有效地重新加载结构?
【发布时间】:2016-11-02 00:17:24
【问题描述】:

我找到了一个最小的例子,展示了我在学习 Elixir 时遇到的一个问题。

我写了一个脚本:

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 以某种方式缓存

两个问题:

  • 这是错误还是设计决定?
  • 有没有更聪明的解决方法?

【问题讨论】:

  • 在将文件更改为包含:b 后,您正在启动一个全新的iex "filename",对吗?我无法在我的系统上重现它。
  • 像@Dogbert 我试过这个,但我无法在我的系统上重现这个问题。你能分享更详细的复制步骤吗?
  • 我这样做是的,我使用 Interactive Elixir (1.2.3) - 按 Ctrl+C 退出(键入 h() ENTER 以获得帮助)
  • 可能有点远,但请在您的 iex 中尝试r P。如果你保存了文件,它应该重新编译并重新加载模块。

标签: elixir elixir-iex


【解决方案1】:

主要问题是你的结构模块上有函数。这会导致像你看到的问题。您需要将结构和功能分开。如果你愿意,你可以在你的模块中嵌套结构模块。

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

【讨论】:

    猜你喜欢
    • 2019-06-20
    • 1970-01-01
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    相关资源
    最近更新 更多