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.

+3


source to share


1 answer


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(...

      

+3


source







All Articles