在一系列 Erlang 匹配中,我如何判断其中哪一个失败了?
In a sequence of Erlang matches, how do I tell which one of them has failed?
考虑以下片段:
do_stuff() ->
% assume each of BoundVarI is bound here
BoundVar1 = term1(),
BoundVar2 = term2(),
% ...
BoundVarN = termN(),
ok.
do_stuff_wrapper() ->
do_stuff().
在包装函数 (do_stuff_wrapper/0
) 中,我如何准确地确定哪一个匹配项失败了?需要明确的是,我不是在寻找一种方法来判断它 只是 失败,可能是通过生成和监视进程,而是一种方法来判断 哪个 的比赛导致失败。我考虑过的一种方法是只从错误元组中提取行号,但我觉得这会大大损害可维护性。
您可以按照以下方式尝试:
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.
根据实际问题,我会选择其中之一(或两者都不选),但这些示例显示了您可以调整的不同方法。
考虑以下片段:
do_stuff() ->
% assume each of BoundVarI is bound here
BoundVar1 = term1(),
BoundVar2 = term2(),
% ...
BoundVarN = termN(),
ok.
do_stuff_wrapper() ->
do_stuff().
在包装函数 (do_stuff_wrapper/0
) 中,我如何准确地确定哪一个匹配项失败了?需要明确的是,我不是在寻找一种方法来判断它 只是 失败,可能是通过生成和监视进程,而是一种方法来判断 哪个 的比赛导致失败。我考虑过的一种方法是只从错误元组中提取行号,但我觉得这会大大损害可维护性。
您可以按照以下方式尝试:
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.
根据实际问题,我会选择其中之一(或两者都不选),但这些示例显示了您可以调整的不同方法。