Print out variable name in Elixir
Warning: this is an attempt to be smart. I know I should probably just leave it readable, but that doesn't mean I don't want to know how to be smart: -P
I have something like this (contrived example):
def glue(%{"alpha" => alpha, "beta" => beta}) do
cond do
alpha && beta ->
alpha <> beta
alpha ->
IO.puts("oops, you forgot to give me alpha!")
true ->
IO.puts("oops, you forgot to give me beta!")
end
end
but would like instead:
def glue(%{"alpha" => alpha, "beta" => beta}) do
cond do
alpha && beta ->
alpha <> beta
true ->
something
|> need_field()
end
end
defp need_field(something) do
IO.puts("oops, you forgot to give me " <> something)
end
Is there a clever way to get the name of an empty variable?
I was thinking about using it somehow alpha || beta
to get filled in and then print the name of another, but I just can't seem to get there.
source to share
You have to be careful with matching on maps. If the card does not contain a key, then your head will not match the function. You can do it:
def glue(%{"alpha" => alpha, "beta" => beta} = map) do
cond do
alpha && beta ->
alpha <> beta
true ->
need_field(map)
end
end
defp need_field(map) do
Enum.each(map, fn
{k, nil} -> IO.puts "You forgot to give me #{k}"
_ -> nil
end
end
Now, if you expect the card to be missing from the field, you can add a second function clause:
def glue(map) do
Enum.each ~w(alpha beta), fn key ->
if map[key], do: nil, else: IO.puts("You forgot to give me #{key}")
end
end
Here is the complete solution if displaying it.
def glue(%{"alpha" => alpha, "beta" => beta} = map) do
cond do
alpha && beta ->
alpha <> beta
true ->
need_field(map)
end
end
def glue(map) do
Enum.each ~w(alpha beta), fn key ->
if map[key], do: nil, else: IO.puts("You forgot to give me #{key}")
end
end
defp need_field(map) do
Enum.each(map, fn
{k, nil} -> IO.puts "You forgot to give me #{k}"
_ -> nil
end
end
If the input is a struct, then you don't need to worry about the default as the struct must have all the keys. In this case, you can get the keys from the structure
map
|> Map.from_struct
|> Enum.each(...
source to share