/var/log/messages

Feb 19, 2019 - 1 minute read - Comments - programming

Metaprogramming Elixir (8)

Macro.to_string で生成されたコードを理解、という小休憩てきな節。Translator module に以下な修正を、とのこと。

  def compile(translations) do
    translations_ast = for {locale, mappings} <- translations do
      deftranslations(locale, "", mappings)
    end

    final_ast = quote do
      def t(locale, path, binding \\ [])
      unquote(translations-ast)
      def t(_locale, _path, _bindings), do: {:error, :no_translation}
    end

    IO.puts Macro.to_string(final_ast)
    final_ast
  end

もともとの compile は final_ast に格納される AST を戻す手続きだったのですが Macro.to_string するために、という事ですね。で、コンパイルしてみました。

iex(1)> c "macro_to_string.exs"
[Translator]
iex(2)> c "i18n.exs"
(
  def(t(locale, path, binding \\ []))
  [[[def(t("fr", "flash.hello", bindings)) do
    "Salut %{first} %{last}!"
  end, def(t("fr", "flash.bye", bindings)) do
    "Au revoir, %{name}!"
  end], [def(t("fr", "users.title", bindings)) do
    "Utilisateurs"
  end]], [[def(t("en", "flash.hello", bindings)) do
    "Hello %{first} %{last}!"
  end, def(t("en", "flash.bye", bindings)) do
    "Bye, %{name}!"
  end], [def(t("en", "users.title", bindings)) do
    "Users"
  end]]]
  def(t(_locale, _path, _bindings)) do
    {:error, :no_translation}
  end
)
[I18n]

いまだに以下のソレが理解できていなかったりしています。

 def(t(locale, path, binding \\ []))

というか色々不思議。unquote(translations_ast) が戻すリストも色々アレです。内包 for は

    translations_ast = for {locale, mappings} <- translations do
      deftranslations(locale, "", mappings)
    end

deftranslations のリストを戻す、ので

        quote do
          def t(unquote(locale), unquote(path), bindings) do
            unquote(interpolate(val))
          end
        end

な、例えば

def(t("fr", "flash.hello", bindings)) do
    "Salut %{first} %{last}!"
end

がリストの要素の一つ、になるのか。現時点では interpolate は

  defp interpolate(string) do
    string # TBD: interpolate bindings within string
  end

なのでそのまんま、なのですね。

Final Step

次のエントリにて。

Metaprogramming Elixir (7) Metaprogramming Elixir (9)

comments powered by Disqus