我正在尝试改进我的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
能够接受bitstring
和list
个参数。
答案 0 :(得分:2)
我会将将路径规范化的部分提取到单独的方法中。它基本上需要处理两种情况:
但是,由于单引号字符串被实现为字符列表这一事实,当有人意外地将这样的值传递给您的库时,我发现了一个问题。它将被检测为列表,并可能导致库内部出现错误,而不是提供有用的错误消息。这意味着您还需要处理以下两种情况:
我建议您尝试将潜在的字符列表转换为适当的字符串。
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"]