1

Elixir の学習中に遭遇する問題の 1 つを示す最小限の例を見つけました。

私はスクリプトを書きます:

defmodule P do
  defstruct a: 2
  def geta(%P{a: a}), do: a
end

動作するセッションチェックiex "filename"を開始するために使用しますiexP.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によってキャッシュされているように見えます。

2 つの質問:

  • これはバグですか、それとも設計上の決定ですか?
  • それを回避するためのより賢い方法はありますか?
4

1 に答える 1

0

主な問題は、構造体モジュールに関数があることです。それはあなたの見ているような問題を引き起こします。構造体と関数を分離する必要があります。必要に応じて、構造体モジュールをモジュール内にネストできます。

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> P.geta(%P.Data{a: 10})
10
iex> P.getb(%P.Data{a: 3, b: 24})
24
于 2016-07-07T01:13:29.080 に答える