在Elixir中打印变量名称

时间:2017-05-03 19:02:12

标签: elixir phoenix-framework

警告:这是一个聪明的尝试。我知道我可能只是让它可读,但这并不意味着我不想知道如何聪明:-P

我有这样的事情(人为的例子):

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

但我想改为:

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

有没有一种聪明的方法来获取空变量的名称?

我正在考虑使用alpha || beta来获取填充的那个,然后打印另一个的名称,但我似乎无法到达那里。

1 个答案:

答案 0 :(得分:3)

您必须小心匹配地图键。如果地图不包含密钥,那么您的功能头将不匹配。你可以这样做:

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

现在,如果您希望地图缺少该字段,那么您可以添加第二个函数子句:

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

如果是地图,这是完整的解决方案。

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

如果输入是结构,那么你不必担心default子句,因为struct必须拥有所有键。在这种情况下,您可以通过

从结构中获取密钥
map
|> Map.from_struct 
|> Enum.each(...