There’s no ability to create a string template variable? For instance:
defmodule M1 do
@my_str_var "aaaaa{key1}bbbbb{key2}cccc" # this
def get_string(var1, var2) do
# but then how to use it?
# String.interpolate(@my_str, var1, var2)
# or
# String.interpolate(@my_str, %{key1: var1, key2: var2})
end
end
It’s worth noting that EEx.eval_string isn’t very fast. The EEx module documentation has more information on its use, I would suggest that you want the function_from_string macro.
I think the core point is that you don’t store “template strings” but you can store strings and then combine them yourself, with bespoke code or a library.
Only when you want to evaluate the template during runtime for each time you want to apply it.
If though, you use the macros provided by eex to compile the templates at compile time of your program and inject a runtime optimized version in your code, then eex is fast enough.
phoenix uses eex by default, but is rendering templates slow? No, not really, we still manage to get sub millisecond responses, despite having to use “slow” eex.
Maybe my post was not clear enough: What I showed you was what a function like the function_from_string macro would do.
While the parsing part is ‘slow’ (but no slower than any way you might be able to do this manually), you only have to do it once, and then can re-use it every time you fill it in. You can even (and this is what e.g. Phoenix does) run the parsing step at compile-time.
This is the only way to store a ‘template string’ directly without using e.g. EEx would be to store it as quote do "aaa#{x}bbb#{y}ccc" end and later on ‘embed’ it from within another macro that you write. That is probably very messy.
defmodule Foo do
def get_string(var1, var2) do
# do stuff ...
bar = my_tpl_str(var1, var2)
# etc
end
defp my_tpl_str(k1, k2), do: "aaaaa#{k1}bbbbb#{k2}ccccc"
end
I will ask question than no one else did: what you do with value returned from get_string/2? If you are sending it over the wire or save it to the file, then maybe you should check iodata() instead, so your “template” would look like:
def get_string(var1, var2) when is_string(var1) and is_string(var2) do
["aaaaa", var1, "bbbbb", var2, "cccc"]
end
IO.puts get_string("foo", "bar") # => aaaaafoobbbbbbarcccc
Yeah, I’m super late to this all, but I’d most definitely wrap this in a function. I’m going to give you the answer that I personally needed, going into the detail that I lacked when I came here with this same question, for posterity.
I think that this is using @variables beyond their scope. The @ symbol denotes a Module Attribute, which is constant. While module attributes serve many purposes (like annotations with @doc), when used functionally, just think that the values replace their references at compile time, and in this case, a string template variable is, by nature and name, variable.
So in action, if you have @my_token "1234", wherever you put @my_token, at compile time, the language will just “swap” (loosely) every instance of @my_token with the string value “1234”.