export_to (Was: Re: the OO metaphor)

Luke Gorrie <>
Fri Dec 1 14:32:54 CET 2000


Ulf Wiger <> writes:

> Hehe, I'd like to see some code that actually does something useful by
> calling module info, and then simply going through the list of
> exported functions and calling them, just to see what would happen.

What a fine idea! I present "modinfo": No more reading tedious
documentation or understanding source code, from now on Erlang
programmers can learn new APIs with easy-to-use commands like:

  ()2> modinfo:probe(random).
  [{random,seed,[]},
   {random,seed,[[integer,integer,integer]]},
   {random,uniform,[]},
   {random,uniform,[[integer],[float]]},
   {random,module_info,[]},
   {random,module_info,[]}]

Or if you just want to check the arguments of a particular function:

  ()3> modinfo:probe_fun(lists, map, 2).
  {lists,map,[[fun1,string],[fun1,list]]}

Optionally can be used to automatically generate programs by probing
side-effecty modules :-)

Cut here.

-module(modinfo).
-author('').

-compile(export_all).			% *grin*

%% Call each function of Mod with lots of argument permutations, and
%% return a list of what doesn't crash.
probe(Mod) ->
    [FunsWithArity] = [Exports || {exports, Exports} <- Mod:module_info()],
    [probe_fun(Mod, Fun, Arity) || {Fun, Arity} <- FunsWithArity].

%% Call Mod:Fun/Arity with lots of argument permutations and show
%% which ones don't crash.
probe_fun(Mod, Fun, Arity) ->
    {Mod, Fun, [Types || {ok, Types} <- call_fun(Mod, Fun, Arity)]}.

call_fun(Mod, Fun, Arity) ->
    Searchspace = combos(Arity),
    [try_call(Mod, Fun, Args) || Args <- Searchspace].

try_call(Mod, Fun, Args) ->
    case catch apply(Mod, Fun, values(Args)) of
	{'EXIT', _} ->
	    error;
	_ ->
	    {ok, types(Args)}
    end.

values(ArgList) -> [Value || {Type, Value} <- ArgList].
types(ArgList)  -> [Type  || {Type, Value} <- ArgList].

combos(0) -> [];
combos(1) -> [[Arg] || Arg <- args()];
combos(N) -> [[X|Y] || X <- args(),
		       Y <- combos(N-1)].

%% {Type, Value} of some arguments to try
args() -> [{integer, 1}, {float, 1.0}, {string, "foo"}, {list, [a, b, c]},
	   {atom, foo}, {ref, make_ref()}, {pid, self()}, {tuple, {a, b}},
	   {fun0, fun() -> ok end},
	   {fun1, fun(X) -> X end},
	   {fun2, fun(X, Y) -> X end}].





More information about the erlang-questions mailing list