请为多类型参数建议惯用的Elixir

时间:2015-02-11 00:28:01

标签: elixir

我正在尝试改进我的Elixir库的代码,如下所示:

def dirs(path, regex_dir \\ ".+") when (is_bitstring(path) or is_list(path)) do
  file_path = case String.valid? path do
    true -> [path]
    false -> path
  end
  do_dirs(file_path, [], regex_dir)
end

defp do_dirs([], result, regex_dir) do
  result
end

defp do_dirs(paths ,result, regex_dir) do
  [h | t] = paths
  do_dirs(t, result ++ dirs_list(h, regex_dir), regex_dir)
end

defp dirs_list(path, regex_dir) when is_bitstring(path) do
  Finder.new()
  |> Finder.with_directory_regex(Regex.compile!(regex_dir))
  |> Finder.only_directories()
  |> Finder.find(Path.expand(path))
  |> Enum.to_list
  |> Enum.sort
end

我特别讨厌检查file_path是否是有效字符串的部分,但我无法找到一种方法来美化它或使它成为更惯用的Elixir。我希望dirs能够接受bitstringlist个参数。

1 个答案:

答案 0 :(得分:2)

我会将将路径规范化的部分提取到单独的方法中。它基本上需要处理两种情况:

  • 位串
  • bitstings列表

但是,由于单引号字符串被实现为字符列表这一事实,当有人意外地将这样的值传递给您的库时,我发现了一个问题。它将被检测为列表,并可能导致库内部出现错误,而不是提供有用的错误消息。这意味着您还需要处理以下两种情况:

  • 字符列表
  • 角色列表列表

我建议您尝试将潜在的字符列表转换为适当的字符串。

def dirs(path, regex_dir \\ ".+") do
  path
  |> normalize_path
  |> do_dirs([], regex_dir)
end

# list of bitstrings
defp normalize_path([path | rest]) when is_bitstring(path) do
  [path | normalize_path(rest)]
end

# list of character lists
defp normalize_path([path | rest]) when is_list(path) do
  [to_string(path) | normalize_path(rest)]
end

defp normalize_path([]) do
  []
end

# bitstring
defp normalize_path(path) when is_bitstring(path) do
  [path]
end

# character list
defp normalize_path(path) when is_list(path) do
  [to_string(path)]
end

它将执行以下转换:

normalize_path 'foo'             #=> ["foo"]
normalize_path "foo"             #=> ["foo"]
normalize_path ['foo', 'bar']    #=> ["foo", "bar"]
normalize_path ["foo", "bar"]    #=> ["foo", "bar"]
normalize_path ["foo", 'bar']    #=> ["foo", "bar"]
normalize_path ['foo', "bar"]    #=> ["foo", "bar"]