如果我们有这样的模块名称:
Module.V1.CountryTest
我可以将它转换为String,如下所示:
Module.V1.CountryTest |> to_string
现在我在iex
module = Module.V1.CountryTest |> to_string
"Elixir.Module.V1.CountryTest"
iex(2)> replace = Regex.replace(~r/Test/, module, "")
"Elixir.Module.V1.Country"
iex(3)> replace |> String.to_atom
Module.V1.Country
所以,如果我删除Test
。并将其转换回atom
。它会给我回模块名称。但是,如果我replace
或remove
模块名称中的任何其他内容,它会为我提供此输出:
some = Regex.replace(~r/Country/, replace, "")
"Elixir.Module.V1."
iex(5)> some |> String.to_atom
:"Elixir.Module.V1."
有人可以解释一下这种行为吗?为什么它不允许任何其他部件更改或更换。意思是像这样给我回输出
Module.V1.Country
我的意思是,如果可能的话。
感谢。
答案 0 :(得分:9)
Elixir模块名称只是以"Elixir."
为前缀的原子。 Elixir打印以"Elixir."
开头并包含有效Elixir模块名称的原子,之后与其他原子不同:
iex(1)> :"Elixir.Foo"
Foo
iex(2)> :"Elixir.F-o"
:"Elixir.F-o"
当您替换Test
时,其余值是有效的Elixir模块名称,但当您替换Country
时,最后会得到.
不是有效的模块名称。如果你也删除了点,你会得到你想要的东西:
iex(3)> Module.V1.Country |> to_string |> String.replace(~r/Country/, "") |> String.to_atom
:"Elixir.Module.V1."
iex(4)> Module.V1.Country |> to_string |> String.replace(~r/\.Country/, "") |> String.to_atom
Module.V1
答案 1 :(得分:0)
要将字符串转换为模块,您可能需要使用 Module.safe_concat/1
或 /2
:
Module.safe_concat(Module.V1, "CountryTest") # => Module.V1.CountryTest
Module.safe_concat(~w[Module V1 CountryTest]) # => Module.V1.CountryTest