elixir

Setting existing struct value in Elixir?


Is it possible to have a function for setting values inside an existing struct? I'm talking about the idea of passing the existing struct into a function and setting that structs "name" value (for example)?

What I have:

main.exs

  Code.require_file("user.exs") # Requiring in module

  person1 = User.constructor("Name") # Making a new user

  IO.write inspect person1

user.exs

defmodule User do
  defstruct [name: ""]

  def constructor(name) do
    %User{name: name}
  end
end

Any way to get this idea working?

def setName(struct, newName) do
  struct.name = newName
end

Thanks


Solution

  • Absolutely. There are several ways this can be accomplished.

    Method 1

    This will error at compile time when trying to set a field missing from the struct

      defmodule User do
        defstruct name: nil
        def set_name(user, name) do
          %{user | name: name}
        end
      end
    

    Method 2

    This will silently discard invalid keys

        def set_name(user, name) do
          user |> struct(%{name: name})
        end
    

    Method 3

    This will input invalid keys into the struct

        def set_name(user, name) do
          user |> Map.put(:name, name)
        end
    

    Method 4 & 5

    These will raise a runtime error when trying to set a field that is not in the struct

        def set_name(user, name) do
          user |> struct!(%{name: name})
        end
    
        def set_name(user, name) do
          user |> Map.update!(:name, name)
        end