Debunk Perl's magic with B::Deparse

The B::Deparse module compiles a Perl program and then deparses it, producing the internally generated source code. What’s the point of that you say? Well it let’s you look behind the curtain and inspect how Perl is structuring the program code which can help you debug it, among other things.

Example

Consider the slurpy parameter optimization from this week’s subroutine signatures article. We know from speed benchmarks that the signature becomes ~30% faster with a slurpy parameter, and we can reason about why that is the case, but B::Deparse can show us why. Here is the code for two signatures, one normal and one using the slurpy parameter:

use feature 'signatures';

sub normal_signature ($foo) {}

sub slurpy_signature ($foo, @) {}

Now if we save the code as signatures.pl, we can use B::Deparse to inspect it at the command line:

$ perl -MO=Deparse signatures.pl

This generates the following output:

sub normal_signature {
    use feature 'signatures';
    die 'Too many arguments for subroutine' unless @_ <= 1;
    die 'Too few arguments for subroutine' unless @_ >= 1;
    my $foo = $_[0];
    ();
}
sub slurpy_signature {
    use feature 'signatures';
    die 'Too few arguments for subroutine' unless @_ >= 1;
    my $foo = $_[0];
    ();
}
signatures.pl syntax OK

The generated code shows how Perl structured the signatures.pl code internally. You can see how “slurpy_signature” has one fewer die statement. This explains the improved performance as the subroutine has less to do. Magic debunked!

More on B::Deparse

B::Deparse comes with extensive documentation and has some useful options for altering the output.

One of the many gems in brian d foy’s Mastering Perl book is the B::Deparse entry in the “Cleaning up Perl” chapter (affiliate link). In the book brian shows several uses for B::Deparse including debugging one-liners and decoding obfuscated code. You can read a draft version of the chapter online here.

PerlMonks has an interesting entry for those curious as to why the command line use of B::Deparse is “-MO=Deparse” and not “-MB::Deparse”.

Thanks

Thanks again to Perl Pumpking and teflon man Ricardo Signes who put me on to using B::Deparse on subroutine signatures.

Cover image © bark image has been digitaly altered

Tags

David Farrell

David is the founder and editor of PerlTricks.com. An organizer of the New York Perl Meetup, he works as a technology consultant in New York City.

Browse their articles