在一系列Erlang匹配中,我如何判断哪一个匹配失败?

jv4diomz  于 2022-12-20  发布在  Erlang
关注(0)|答案(1)|浏览(198)

请看下面的代码片段:

do_stuff() ->
    % assume each of BoundVarI is bound here
    BoundVar1 = term1(),
    BoundVar2 = term2(),
    % ...
    BoundVarN = termN(),
    ok.

do_stuff_wrapper() ->
    do_stuff().

在 Package 函数中(do_stuff_wrapper/0),我如何准确地确定哪一个匹配失败了呢?需要说明的是,我并不是在寻找一种方法来判断它 * 刚刚 * 失败了(可能是通过生成和监视一个进程),而是寻找一种方法来判断 * 哪一个 * 匹配导致了失败。我考虑的一种方法是从错误元组中提取行号,但我觉得这对可维护性伤害很大。

0lvr5msh

0lvr5msh1#

你可以尝试一些沿着的方法:

ScopeRef = make_ref(), %% To make sure to catch only errors in this scope
try
  {_, BoundVar1} = {{ScopeRef, term1}, term1()},
  {_, BoundVar2} = {{ScopeRef, term2}, term2()},
  {_, BoundVarN} = {{ScopeRef, termN}, termN()},
  %% ^ Consider turning this into a lists:foreach/recursion
  ok
catch %% First error stops execution
  error:{badmatch, {{ScopeRef, FailedFunName}, _FailedTerm}} -> {error, {nomatch, FailedFunName}}
end.

或者如果你想检查每一个

BoundTerms = [BoundVar1, BoundVar2, BoundVarN],
AssertFuns = [fun term1/0, fun term2/0, fun termN/0],
FailedTerms = lists:reverse(lists:foldl(fun({BoundVar, AssertFun} = Pair, Acc) ->
  case AssertFun() of
    BoundVar -> Acc;
    _ -> [Pair | Acc]
  end
end, [], lists:zip(BoundTerms, AssertFuns)),
case FailedTerms of
  [] -> ok;
  _ -> exit({assert_failed, FailedTerms})
end.

根据实际的问题,我会选择其中一种(或者两种都不选),但是这些示例显示了您可以调整的不同方法。

相关问题