Rename struct field; how to get iex to pick it up?

When working in iex, how do you ‘re define’ a module after changing the name of a structs field?

Using the new field name in e.g. a parameter list gives me an error.

1 Like

You can use r MyModule in iex to recompile and reload the module that contains the struct.

Just type h r in iex for more information.

-vincent

1 Like

I’ve tried that and it doesn’t work. First load this:

defmodule Fubar do
  defstruct f: nil
  def bar(%Fubar{f: f}), do: nil
end

Then change the code - rename f to x in defstruct line and function def.

defmodule Fubar do
  defstruct x: nil
  def bar(%Fubar{x: f}), do: nil
end

Which results in this:

iex(4)> r Fubar
warning: redefining module Fubar (current version defined in memory)
  lib/struct.ex:1

** (CompileError) lib/struct.ex:3: unknown key :x for struct Fubar
    (stdlib) lists.erl:1353: :lists.mapfoldl/3

The warning I get. That’s OK. But the error?

The error supprises me too to be honest. It must have something to do with structs being checked at compile time. If you for example do a mix compile in another terminal, it compiles fine and in iex doing l Fubar (which only loads the module again) works too.

Maybe somebody else can explain the difference between doing r MyModule in iex, or doing an mix compile, followed by l MyModule in iex.

Keep in mind though that if you go the mix compile and l Fubar route, variables in iex are never ‘upgraded’. So if you do something like:

iex> x = %Fubar{}
iex> l Fubar

x will now be an invalid Fubar struct if Fubar’s struct definition is modified. Which could be exactly the reason that r Fubar behaves as it does when I think about it now :slight_smile:

-vincent

1 Like