Tuesday, August 22, 2006

New Smerl Capability: Embedding Values in Place of Arbitrary Function Parameters

I added a couple of new functions to Smerl to make Erlang metaprogramming with Smerl even more powerful. They provide a capability similar to metacurrying, but more flexible.

smerl:embed_params/2 takes a function form and a list of {Name, Value} pairs. For all clauses of the function, it iterates through their parameters, replacing each parameter that matches an item in the list with a variable in the body of the function that is bound to the item's value.

Reading the above sentence may feel like getting hit by a truck, so let's take a look at an example:

M1 = smerl:new(foo),
{ok, M2} = smerl:add_func(M1, "bar(A,B,C) ->
io:format(\"~s ~s ~s\", [A,B,C])."),
{ok, F1} = smerl:get_func(M2, bar, 3),
F2 = smerl:embed_params(F1, [{'A', "Lucy"}, {'C', "Sky"}]),
{ok, M3} = smerl:add_func(M2, F2),
foo:bar("in the"). %% outputs "Lucy in the Sky"

The other function I added is smerl:embed_all/2. This function takes a MetaMod object (the thing you get back when calling smerl:new/1, smerl:for_module/1, or smerl:for_file/1), and applies smerl:embed_params/2 to all functions in the module. Sounds bizzare? It may be, but I have found it useful in a project I got cooking :)


No comments: