是否可以编写一个返回指定arity的匿名函数的函数?我希望能够生成一个函数,它可以作为第三个参数传递给meck:expect/3,这样我就可以动态模拟任何arity的现有函数?我已经做了相当多的搜索,似乎解决这个问题的唯一方法是硬编码如下:
meck:expect/3
gen_fun(1, Function) -> fun(A) -> Function([A]) end; gen_fun(2, Function) -> fun(A, B) -> Function([A, B]) end; ...
zzwlnbp81#
它并不漂亮,但您可以使用与shell相同的技巧,* 从头开始 * 构建您的函数:
-module(funny). -export([gen_fun/1, gen_fun/2]). -spec gen_fun(function()) -> function(). gen_fun(Function) -> {arity, Arity} = erlang:fun_info(Function, arity), gen_fun(Arity, Function). -spec gen_fun(non_neg_integer(), function()) -> function(). gen_fun(Arity, Function) -> Params = [{var, 1, list_to_atom([$X| integer_to_list(I)])} || I <- lists:seq(1, Arity)], Anno = erl_anno:new(1), Expr = {'fun', Anno, {clauses, [{clause, Anno, Params, [], [{call, Anno, {var, Anno, 'Function'}, Params}]}]}}, {value, Fun, _Vars} = erl_eval:expr(Expr, [{'Function', Function}]), Fun.
然后,在贝壳里......
1> F = funny:gen_fun(fun io:format/2). #Fun<erl_eval.43.40011524> 2> F("~ts~n", ["😑"]). 😑 ok 3> F1 = funny:gen_fun(fun io:format/1). #Fun<erl_eval.44.40011524> 4> F1("😑~n"). 😑 ok 5>
1条答案
按热度按时间zzwlnbp81#
它并不漂亮,但您可以使用与shell相同的技巧,* 从头开始 * 构建您的函数:
然后,在贝壳里......