使用fun作为范围有什么缺点

时间:2014-03-13 12:48:56

标签: macros erlang

我编写了一个类似于以下内容的宏来进行简洁的日志记录:

-define(MY_MACRO(Expr, Params),
    case Expr of
        {correct_return, X} -> X;
        Result -> io:format("Unexpected result (~p:~p): ~p", [ ?MODULE, ?LINE, [
            {expr, ??Expr, Result},
            {params, ??Params, Params}
        ]]),
        undefined
    end).

但在同一范围内使用两次时遇到错误variable 'Result' unsafe in case。以下代码解决了我的问题,但我想知道它的缺点。

-define(MY_MACRO(Expr, Params), (fun() ->
    case Expr of
        {correct_return, X} -> X;
        Result -> io:format("Unexpected result (~p:~p): ~p", [ ?MODULE, ?LINE, [
            {expr, ??Expr, Result},
            {params, ??Params, Params}
        ]]),
        undefined
    end end)()).

或许,是否有更好的解决方案?

2 个答案:

答案 0 :(得分:3)

你的第二个解决方案可能是最好的。由于所有代码都很有趣,因此您不会引入任何新的变量绑定,并避免许多意外。 (如果您的原始代码在第二个case子句中使用了X而不是Result,那么您将不会遇到该错误,但第二个宏实例化将与 first <匹配< / em>结果。)

顺便说一下,你的宏看起来非常类似于eunit的assertEqual宏。您可以直接使用它,或从eunit.hrl获取其定义并根据您的需要进行修改。

答案 1 :(得分:2)

您可以使用begin…end代替(fun () -> … end)()

  • 我认为这是一个范围问题。我不确定begin…end的范围是否合理fun
  • 我不确定创建一个有趣的事情只是后来调用它是编译器优化的东西,但我已经看过它的讨论。
  • This should interest you.