[Distel-hackers] First "refactoring" command
Status: Beta
Brought to you by:
lukeg
From: Luke G. <lu...@bl...> - 2003-01-14 19:50:26
|
Hello everyone, welcome to the year 2003 :-) I just checked in a refactoring command in CVS, called erl-refactor-subfunction, and bound to "C-c C-d f". Suppose we have a function like this: eval_expression(S) -> case parse_expr(S) of {ok, Parse} -> case catch erl_eval:exprs(Parse, []) of {value, V, _} -> {ok, flatten(io_lib:format("~p", [V]))}; {'EXIT', Reason} -> {error, Reason} end; {error, {_, erl_parse, Err}} -> {error, Err} end. Futher suppose that we want to tidy up by making the 'case' expression into a separate function. We can do this automatically, by first selecting the region from 'case' to 'end', and then running erl-refactor-subfunction. It will prompt us for for the name of our new function, and we can enter "try_evaluation". It then replaces the 'case' expression with a call to our new function, passing in any variable(s) it needs, so we end up with: eval_expression(S) -> case parse_expr(S) of {ok, Parse} -> try_evaluation(Parse); {error, {_, erl_parse, Err}} -> {error, Err} end. Which is all good and well, but we still need the actual function definition. That gets put on the kill ring, so that we can put it where we want manually. So, the next time we "yank" with C-y, we will get: try_evaluation(Parse) -> case catch erl_eval:exprs(Parse, []) of {value, V, _} -> {ok, flatten(io_lib:format("~p", [V]))}; {'EXIT', Reason} -> {error, Reason} end. And then our program works again! One caveat: any variable bindings created in the new function will not get exported back out, so it's possibly to break a program with this command if you use it recklessly :-) Thanks to Richard Carlsson for doing all the work! And for demonstrating how bloody easy it is to use his syntax_tools package :-) P.S.: You have to download syntax_tools 1.2 and stick it in your load path (e.g. using the ~/.erlang file) for this to work. You can download it from erlang.org's contributions page. (Sorry about the delay in implementing this, Richard. I needed a while to write enough sufficiently ugly code to motivate it :-)) Cheers, Luke |