2014-03-13 2 views
1

я написал макрос как следующие лаконичный лесозаготовок:Каковы недостатки использования потехи как сферы

-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)()). 

Или, может быть, есть лучшее решение?

ответ

3

Ваше второе решение, вероятно, является наилучшим. Поскольку весь код находится в забаве, вы не вводите никаких новых привязок переменных и избегаете многих неожиданностей. (Если исходный код был использован X вместо Result во втором пункте случае, вы бы не получили эту ошибку, но вторая макроконкретизация будет соответствовать против первого результата.)

Кстати, ваш макрос очень похож на макрос eUNIT assertEqual. Вы можете использовать это сразу или принять свое определение от eunit.hrl и изменить его для своих нужд.

2

Вы можете использовать begin…end вместо (fun() -> … end)().

  • Я считаю, что это проблема. Я не уверен, что begin…end 's scoping ведет себя нормально, как fun.
  • Я не уверен, что создание забавы только для того, чтобы называть его потом, это то, что оптимизирует компилятор, но я видел дискуссию об этом.
  • This should interest you.
+1

Я только что проверил. 'begin ... end' не создает новую область. Но ссылка полезна. Благодарю. – citxx

+0

просто используйте 'begin ... end' – BlackMamba

Смежные вопросы