The following code is directly from Phoenix.Template. As you can see, render_template didn’t use var!(assigns). It doesn’t trigger compilation error without it. However, if I remove var! from dynamic function created above, I get compilation error.
{name, quote do
@file unquote(path)
@external_resource unquote(path)
defp unquote(defp)(var!(assigns)) do
_ = var!(assigns)
unquote(quoted)
end
defp render_template(unquote(name), assigns) do
unquote(defp)(assigns)
end
end}
My question is in what ways these two function differ which requires var! in one and not in another?
This defines a function with the name of whatever the value of defp is. This function has a single argument, assigns. var!/1 is used here that one cann use assigns inside of quoted.
defp render_template(unquote(name), assigns) do
unquote(defp)(assigns)
end
This defines a function, which calls the function which we defined earlier, passing in through assigns, as they have been given to this function when called.
In render_templateassigns is known to be used, therefore there cannot ever be a warning. The other created function compiles the AST of the actual template into the module, so it‘s unknown if the template actually makes use of assigns or not. That‘s why the line with var! is added to ensure no warnings will happen, as each case is equaly valid and there‘s no way for the user to silence the warning as well.