Archive for July, 2011

Advanced Perl debugging with Aspect

So I had this huge bunch of Spreadsheet::WriteExcel code where I was generating Excel sheets from some statistics I was gathering and I noticed that everytime I opened the Excel file I got a message with something along the lines “File error: data may have been lost”, but on a casual look the spreadsheet looked fine… but of course the devil is in the details. It turns out that if you happen to Spreadsheet::WriteExcel::write in the same cell twice (or more I guess 🙂 ) that error message is what my Excel produces…. So how to find where the problem is… in this huge bunch of writes…

Enter Adam Kennedy’s excellent Aspect library for Perl, a truly brilliant module!! Thanks Adam!

How did I use it in this case? Here goes…

.... lots of other code....

use Aspect;

my $pointcut = call qr/Spreadsheet::WriteExcel::Worksheet::write$/;
# Observe the $ at the end, otherwise write_string will also match, and we don't want that

...... code passes ...

sub in_my_big_excel_write_block {

my %spcoords = ();
my $before_write = before {
my @args = @{$_->params};
if ( $spcoords{$args[1]}{$args[2]} ) {
croak "Will do double write at coord: ["
. $args[1] . "," . $args[2] . "] = >" . $args[3] . "<\n" . "Previous write at coord: [" . $args[1] . "," . $args[2] . "] = >" .
$spcoords{$args[1]}{$args[2]} . "<\n"; } $spcoords{$args[1]}{$args[2]} = $args[3]; } $pointcut; .... lots of $worksheet->write(...) code....

}

Now my poor perl script will die with a message telling me where and what I tried to write double and what I wrote there previously, now it’s easy to find!

🙂

A more general debugging tip would be this simple “before” advice:


before {
if( ($cnt % 1000) == 0 ) {
my @args = @{$_->params};
print "Calling " . $_->sub_name . " with args : " . Dumper(@args) . "\n";
sleep 1;
}
$cnt++;
} $pointcut;

Neat huh!? And trust me, this is only some small simple example of the power of the Aspect library.

Tags: , , ,

Efficient navigation of source code in (X)emacs

Going back to (X)emacs to code perl and c++ after a couple of years of Java coding in Eclipse I was a bit frustrated of navigating around the code with just pg-up, pg-down and search. For instance when you are looking at some function call and want to have a quick look at the definition of that function and then go back to the function call. The best way that I have discovered to do this so far is using imenu and the built in “mark” system. I set a function key to “imenu”

(global-set-key (kbd "<f3>") 'imenu)

Then with the cursor placed on the function call i press f3 RET, which then (in most cases) takes me to the function definition. When I want to go back I use the fact that imenu “sets the mark” where it left so I can use Ctrl-u Ctrl-SPC, which takes me back to the last “mark position”. First I used Ctrl-x Ctrl-x which also kind of works, but that marks the whole region from the function definition back to the function call, which is usually not what I want.

Also, repeated use of Ctrl-u Ctrl-SPC will continue going back to previous marks set in your buffer. Emacs keeps a “current buffer mark ring” in which it stores the marks that are set in the buffer. It is also good to know that “interactive search” (Ctrl-s) sets the mark where the search started when it leaves so when you have finished searching you can use Ctrl-u Ctrl-SPC to go back to where the search started. You can also manually “set the mark” by pressing Ctrl-SPC if you know this is a position you will soon want to return to.

I also like (global-set-key (kbd “C-<return>”) ‘dabbrev-expand) which kinda does code completion the simple emacs way. Since <tab> is tied up with indentation and Ctrl-space is for setting the mark I like Ctrl-Return.

Further, there are the functions ‘beginning-of-defun’/’end-of-defun’ in CPerl mode these are bound to M-C-a/M-C-e, I global-set these to C-M-right and C-M-left which are in my installation bound to beginning and end of sentence which I have no much use for.

Related:
Search At Point
Emacs Nifty Tricks

Tags: