I have a couple of structs and I want to build one of them depending on some STRING as input:
defmodule Mystruct1 do ... end
defmodule Mystruct2 do ... end
...
defmodule Mystructn do ... end
def get_struct(name) do
name
|> <transformations_here>
|> struct()
end
the_struct = get_struct("Mystruct5")
Naively I’m trying something like
name |> String.capitalize |> String.to_atom |> struct
but I’m getting this error
** (UndefinedFunctionError) function :Mystruct5.__struct__/0 is undefined (module :Mystruct5 is not available)
:Mystruct5.__struct__()
(elixir) lib/kernel.ex:2161: Kernel.struct/3
Besides whether this can be done or not, is this a good idea in order to allow the app to scale by merely adding new structs instead of use pattern matching for every possible input?
Consider writing this out explicitly, unless there are a LOT of Mystructs:
def name_to_module(name) do
case name do
"Mystruct1" -> Mystruct1
"Mysturct3" -> Mystruct3 # NOTE: client sends this one spelled wrong and won't change it
end
end
Advantages:
very clear exactly which modules this could return
@al2o3cr, yes, I also prefer to be explicit. In this case
the input is not coming from the user but from a generated code so I expect no mispelling happening here.
the idea is to keep the same code working and don’t touch it as that library grows with more structs names, it’s a bit of magic, but I was wondering how useful this approach would be.