There’s a variable, which might come as either atom or string (binary in erlang parlance). I need to use it to Access
a Keyword
list with atoms as keys. I surely can put a conditional around the String.to_existing_atom/1
so that I don’t get an exception when the variable is an atom already. But maybe there’s a better way to deal with such situation?
I don’t think there is such a way, you’re better off just writing two function variants for atom and binary argument.
4 Likes
The worst I could come up with is String.to_existing_atom(to_string(foo))
1 Like
I think this is what @dimitarvp suggested:
hash_map = %{foo: "Foo", bar: "Bar"}
defmodule HashMap do
def get(hash_map, key) when is_atom(key), do: hash_map[key]
def get(hash_map, key) when is_binary(key), do: hash_map[String.to_existing_atom(key)]
end
{atom, string} = {hash_map |> HashMap.get(:foo), hash_map |> HashMap.get("bar")}
# Output
# {"Foo", "Bar"}
If you pass non existent keys in, you get nil values back, no exception.
P.S. I just wrote it for practice, as I am learning Elixir.
1 Like
If you’re only looking in a Keyword list, you could bypass the Access behaviour and do your own lookup to avoid needing to turn a string into an atom at all.
def lookup(keyword, key) when is_atom(key) do
Keyword.get(keyword, key)
end
def lookup(keyword, key) when is_binary(key) do
# just an example of one way to do this approach
if pair = Enum.find(keyword, fn {k, _v} -> Atom.to_string(k) == key end) do
elem(pair, 1)
end
end
1 Like