I'm creating a new Elixir library that require to be executed with different versions of the language.
This library uses the Erlang :crypto.hmac
function but this function was replaced on version 22 of Erlang OTP by :crypto.mac
(with same functionality).
I'm using the following private macro to execute the newer or older functions:
defmacrop hmac(key, data) do
if System.otp_release() >= "22" do
quote do: :crypto.mac(:hmac, :sha256, unquote(key), unquote(data))
else
quote do: :crypto.hmac(:sha256, unquote(key), unquote(data))
end
end
And using it in the following way:
hmac(key, data)
Two questions:
- Is this a correct way of execute code based in the OTP release version?
- Any better obvious way to address this problem?
Thanks.
2条答案
按热度按时间ercv8c1e1#
这是基于OTP发布版本的正确代码执行方式吗?
您不应检查OTP版本,而应检查应用程序(在本例中为
crypto
)版本。因为OTP版本可能与应用程序版本不同。有没有更好的方法来解决这个问题?
是,检查给定函数是否导出,而不是检查OTP/应用程序的版本。
在运行时,有两种方法可以实现这一点:
或在编译期间:
v9tzhpje2#
宏是编译时的产物,编译后没有宏的踪迹;相反,它注入的AST发生在释放中。
也就是说,如果您希望它是编译时的,这意味着您需要许多环境来编译,并且每个版本都只在编译时的同一平台上工作,这是正确的方法。
如果您希望一次组装一个发行版并使其在不同的目标平台上工作,最好使用
Kernel.apply/3
作为这将在编译时进行评估,相应的功能将在生成的BEAM代码中发生。