Work has sponsored a week of hacking and I've spent it doing stack tricks. I hope to use these features to build a better debugger. For now, here's the latest function. Consider what caller( N ) does. Now consider a goto( N ) that pops the stack back up N frames.
I plan to use it to let a debugger pop up to any level in the currently running program and resume from anywhere reasonable.
I've been playing in Squeak recently and it has the best debugger I've ever seen before. Not only can I inspect any part of the running system, I can modify the code for anything, let the absence of methods or other exceptions serve as breakpoints, pop up a level (or many) in the stack and restart a function.
It's sweet. To make this happen in Perl 5 I'd need the following facilities that
"find the source for the thing that is executing"
"project an editor somewhere useful"
"be able to accept the edited code and replace it in the original file (this is difficult. maybe requires PPI)"
"Merge newly compiled block into running program. (trivial? for non-closures. needs rebinding for closures)"
"pop the stack to some arbitrary point. be able to restart the block"
This is just off the top of my head. Maybe it's not worth doing in Perl 5 but it'd be hella nice to have.
Tonight at SPUG I'm going to be talking about the Perl 5 Virtual Machine focusing on code aspects.
The original slides can be read directly by KPresenter+Kivio at http://diotalevi.isa-geek.net/~josh/Presentations/Perl%205%20VM.odp, as a 8MB Ogg Theora video at http://diotalevi.isa-geek.net/~josh/Presentations/Perl%205%20VM.ogg , or as a kind of sucky fallback HTML at http://diotalevi.isa-geek.net/~josh/Presentations/Perl%205%20VM/html/slide_1.ht
Figured I'd tell you all. It's on CPAN now.
Without any explanation:
Rate perl xs opsperl 1585581/s -- -65% -93%
xs 4573187/s 188% -- -80%
ops 22482894/s 1318% 392% --
I've two work-related thoughts I'd like to explore a little. The first is that I've noticed that the cost of invoking a very small XS accessor/mutator is about the same cost as doing a newSVsv(...) inside it. It occurs to me that I could avoid some copies if lexicals being passed into my accessor were marked as SvTMP if their use was the last mention in the calling code.
Consider:
{
my $foo = 1;
bar( $foo ); # $foo is now stealable
}
I imagine I'd go through the compiled code, find the points where lexicals are last used and insert an operation just prior which would turn the TMP flag on. This is trading a bit of additional space and runtime length for avoiding copies of data. Maybe it helps. Dunno.
Here's the other thought. At work I have lots of records for households of people. To efficiently search for a person and their household, a single household record is exploded out to one for all the people in the dwelling. PostgreSQL has usertypes. I've thought it would be nice to store a set of last names (among other fields) in an array.
Initially looking, the PostgreSQL GIN index type appears to do most of this natively already. I've a drawback in that I can't use multicolumn GIN indexes.
By chance I looked at the tester reports for overload::eval and discovered that its never worked for anyone else. I never got a note about it failing or anything.
How's an author supposed to get notified that stuff is broken? I thought the new cpan test reporting stuff was supposed to make sure I'd get cc-ed on failures. Apparently it doesn't. There's nothing that looks helpful on cpantesters.perl.org either.
I didn't realize until today that the unifying idea behind regular expressions and XPath and all the other nifty pattern matching stuff available in neato-keen languages like Oz, Erlang, Haskell, Prolog, etc is that "regexps" and XPath were just convenient syntaxes to generate input to unification operations.
Consider the expression
'abc' =~
/^[a-z]+\z/
Expanded, the string is the list
[ 'a' 'b' 'c' ]
and conceptually, the regexp is a stream of
any( 'a'
.. 'z' )
values which unify to any of the values a through z.
I gather that this idea that having unification so close to the programmer would let us all do "regexps" on arbitrary data structures more often because we'd just have to express the template streams ala HOP or similar. Apply your template to your data and viola! Destructuring!
%foo = (
a => 1,
b => 2,
c => 3,
d => 4,
);
# Now apply yon unification operator
\ %foo ~~ {
$bar => 1,
$baz => 2,
c => $c,
};
# The following variables would then be populated.
assert( $bar eq 'a' )
assert( $baz eq 'b' )
assert( $c eq '3' )
Sometime in the last few weeks I think I read somewhere in perl-lands that someone had figured out restartable exceptions. I can't remember where I saw it.
Help?
The debugger is loaded and started in a process that wasn't compiled with -d. Neat, eh?
for ( 1
.. 100 ) {
if ( $_ == 50 ) {
eval 'use Enbugger'
}
}
Or maybe you'd like to do something about your exceptions a bit more manually...
if ( my $e = $@ ) {
require Enbugger;
$DB::single = 2;
}
If you weren't aware, the debugger has remote-debugger support. The following starts debugging and opens a console to whatever is listening on port 7000.
local $ENV{PERLDB_OPTS} = 'RemotePort=localhost:7000';
require Enbugger;
$DB::single 2;