chad-adams

chad-adams

Loading of atoms which have been defined in a module's types

I have a simple struct which has a status field which can be :active, :idle, or nil. Definition looks like here:

defmodule Event do
  defstruct status: nil

  @type t :: %__MODULE__{
          status: nil | :active | :idle
        }
end

Then I have an application which parses JSON representation to create instances of these structs. As part of this, I am calling String.to_existing_atom/1. So "active" from the JSON becomes :active. However, I am getting ArgumentError from String.to_existing_atom/1 due to the atom not being loaded yet.

I have tried Jose’s solution on this github thread whereby Code.ensure_loaded?/1 is called to force loading of the module. But in this case, although the module gets loaded, the atoms here are defined in the module’s typing so it doesn’t appear to create them.

Any suggestions on a clean way to solve this?

Marked As Solved

brettbeatty

brettbeatty

In my opinion the better alternative to String.to_existing_atom/1 is to be explicit about which values you’ll cast. For example, if you’re creating an Event struct from a string-keyed map (like parsed JSON), it could look something like this:

def new(map) do
  %__MODULE__{
    ... # other fields
    status: cast_status(map["status"])
  }
end

defp cast_status("active"), do: :active
defp cast_status("idle"), do: :idle
defp cast_status(nil), do: nil

This particular example would raise if you got an unacceptable value back from the JSON. If you need to validate the input, something like Ecto changesets would do the trick too. Or if it fit your needs you could just make everything else nil.

Also Liked

NobbZ

NobbZ

Types and Specs are not available at runtime, and therefore have no effects like creating atoms.

You need to actually use those atoms in your code.

mudasobwa

mudasobwa

Creator of Cure

The sole purpose of String.to_existing_atom/1 would be to raise if the atom is not existing. If you are sure that the source of string in the question is trustful, there is not much sense in using it in general, if the atom already exists, it would be used, atoms are never re-created.

So, AFAICT, this is an XY problem and the simplest although cleanest solution would be to resort to String.to_atom/1 unless you expect values to come from the outside; in that case, it’d be better to handle wrong values in a bit more sophisticated manner.

Where Next?

Popular in Questions Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement