我正在开发一个处理 ETS 的小型库,如果表不存在,我希望能够提前退出函数。我不能把它放在守卫中,因为 Elixir 阻止在守卫中与:ets
交谈,所以我必须基本上在每个函数中都放这个检查,最终看起来像这样可怕的东西(代码是演示 - 我知道它很混乱:)):
def get_and_update(cache, key, modifier) do
unless is_ets_table(cache) do
{ :error, create_error(cache) }
else
set(cache, key, modifier.(get(cache, key)))
end
end
有没有办法将其宏化为以下内容?
deftable get_and_update(cache, key, modifier) do
set(cache, key, modifier.(get(cache, key)))
end
对缺少表的检查将隐式地存储在deftable
宏中。
我已经阅读了宏,但我似乎无法弄清楚到底发生了什么,所以如果你能解释你的答案,我将不胜感激。
除了混乱之外,我还想让开发人员更容易只使用宏名称,而不必总是记住检查表。
提前谢谢。
编辑:我还应该注意,参数的数量可以很容易地(并且会)改变。
我按如下方式实现了这一点,但如果有更好的方法,请告诉我:
defmacro deftable({ func_name, _func_ctx, [cache|_] = args }, do: body) do
quote do
def unquote(func_name)(unquote_splicing(args)) do
if not is_ets_table(unquote(cache)) do
unquote(body)
else
{ :error, no_table(unquote(cache)) }
end
end
end
end