So, if you read my article about why I think Perl 6 is cool, you'll remember that I mentioned that I thought Perl 6 would make it easier to write a Refactoring Browser for Perl. (See http://www.refactoring.com/ for a discussion of what refactoring is, and for pointers to the 'original' refactoring browser)
Within the refactoring community there is the idea of a 'Rubicon' for a 'real' refactoring browser. If your tool can successfully do the 'extract method' refactoring (where a section of code is selected by the user and the browser goes away and turns that into a new method and replaces the selection with an appropriate call to that method, possibly interrogating the user for more information in the process) then it should all be down hill from there...
Anyway. Soon after the article went live, James of this parish pointed out a trick on the london.pm mailing list that got me thinking about how to do 'extract method' in Perl 5. James' trick got me a good long way along the road, and a few steals from B::Deparse and uninit.pm (an unreleased module by Simon Cozens, nag him) and I reached the point where I could do:
my $refactory = Devel::Refactor->new;
my $md = $refactory->extract_method('method_name',
'package'
'print $lex; print');
And then have C<$md->as_string> return
sub method_name {
my $self = shift;
my $lex = shift;
local $_ = shift;
print $lex; print
}
Yeah, the layout is funny. And also C<$md->call_string> would return:
$self->method_name($lex, $_);
Which is quite good. As it stands at the moment you can also pass lexical hashes and arrays too. We also respect fully specified global variables C<$pkg::foo> and don't try and pass them as arguments. And life is very good.
However, we lack the context that the eventual method will be compiled in, so we can't see C