请为多类型参数建议惯用的 Elixir
Please suggest idiomatic Elixir for multi typed arguments
我正在尝试改进我的 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
参数。
我会将规范化路径的部分提取到一个单独的方法中。它基本上需要处理两种情况:
- 位串
- 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"]
我正在尝试改进我的 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
参数。
我会将规范化路径的部分提取到一个单独的方法中。它基本上需要处理两种情况:
- 位串
- 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"]