Warning: this is an attempt to be clever. I am aware that I probably should just leave it readable, but that doesn't mean I don't want to know how to be clever :-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 to instead have:
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 the empty variable?
I was thinking along the lines of somehow using alpha || beta to get the populated one, then print the name of the other one, but I can't quite seem to get there.
You have to be careful with matching on map keys. If the map does not contain the key, then your function head will not match. You could do this:
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 expecting the map to be missing the field, then you could 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 its a map.
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 have to worry about the default clause since a struct has to have all the keys. In this case, you can get the keys from the struct by
map
|> Map.from_struct
|> Enum.each(...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With