<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>From those of you who enjoy modifying existing code at run-time, I would like to ask for some input.</div><div><br></div><div>Inspired by Joe Norton's use of Meck to introduce support for asciiedoc syntax in EDoc [1], I started playing with Meck to do similar things with e.g. tweaking epp on the fly for alternative syntax support.</div><div><br></div><div>I found that Meck was a bit limited in this regard, and ultimately, it's a slight abuse of the tool anyway. Since I maintain the parse_trans application [2], I thought I'd continue my experimentation there (in the module-transforms branch).</div><div><br></div><div>First, I copied meck_mod.erl (into parse_trans_mod.erl) and made a slight addition to it: </div><div><br></div><div>  parse_trans_mod:transform_module(Module, Transforms, Options) -> CompileAndLoadResult</div><div><br></div><div>which fetches the abstract code of a module, transforms it, then compiles and loads the result.</div><div><br></div><div>I then added two helper functions (replace_function/3 and export_function/3), for starters, to help make easy transforms. </div><div><br></div><div>Here's an example [3]:</div><div><br></div><div><div>-module(test_transform_mod).</div><div>-export([ex1/0]).</div><div><br></div><div>-include("codegen.hrl").</div><div><br></div><div>ex1() -></div><div>    parse_trans_mod:transform_module(</div><div>      ex1, [fun(Fs, _Os) -></div><div><span class="Apple-tab-span" style="white-space:pre">         </span>    parse_trans:export_function(int, 0, Fs)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>    end,</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>    fun transform_ex1/2], [{pt_pp_src,true}]).</div><div><br></div><div>transform_ex1(Forms, _Opts) -></div><div>    NewF = codegen:gen_function(add, fun(A, B) -></div><div><span class="Apple-tab-span" style="white-space:pre">                                       </span>     A - B</div><div><span class="Apple-tab-span" style="white-space:pre">                         </span>     end),</div><div>    parse_trans:replace_function(add, 2, NewF, Forms).</div></div><div><br></div><div>A shell dialogue to illustrate:</div><div><br></div><div><div>Eshell V5.8.4  (abort with ^G)</div><div>1> ex1:add(5,3).</div><div>8</div><div>2> test_transform_mod:ex1().</div><div>Pretty-printed in "./ex1.xfm"</div><div>ok</div><div>3> ex1:add(5,3).</div><div>2</div></div><div><br></div><div>This changes the example module ex1 [4], by exporting a previously internal function, int/0, and changing the semantics of the add/2 function.</div><div><br></div><div>The idea is hardly new. Yariv Sadan did something similar with smerl. I wanted to add a few functions that would draw on the stuff already supported by parse_trans.</div><div><br></div><div>For those of you out there who have used similar things before, what kind of support would you like to see?</div><div><br></div><div>BR,</div><div>Ulf W</div><div><br></div><div>[1] <a href="https://github.com/norton/asciiedoc/blob/master/src/asciiedoc_lib.erl#L39">https://github.com/norton/asciiedoc/blob/master/src/asciiedoc_lib.erl#L39</a></div><div><br></div><div>[2] <a href="http://github.com/esl/parse_trans">http://github.com/esl/parse_trans</a></div><div><br></div><div>[3] <a href="https://github.com/esl/parse_trans/blob/module-transforms/examples/test_transform_mod.erl">https://github.com/esl/parse_trans/blob/module-transforms/examples/test_transform_mod.erl</a></div><div><br></div><div>[4] In ex1, add(X, Y) -> X+Y.</div><div>     After transformation, add(A, B) -> A - B.</div><br><div>
<div>Ulf Wiger, CTO, Erlang Solutions, Ltd.</div><div><a href="http://erlang-solutions.com">http://erlang-solutions.com</a></div><div><br></div><br class="Apple-interchange-newline">
</div>
<br></body></html>