Toolkit review: Devel::Local, Devel::SimpleTrace, Reply

Nothing makes a lazy programmer happier than discovering free software that makes her or his job easier. Here are three of my favorites that I use on the daily:

Devel::SimpleTrace

Devel::SimpleTrace will add stack traces to 'die' and 'warn'. If you've ever seen library code that you don't recognize throw an error you don't understand this module should be in your toolkit.

SYNOPSIS

 #adapted/copied from the pod
 $ perl -MDevel::SimpleTrace program_with_strange_errors.pl

or just put a 'use Devel::SimpleTrace' anywhere.

Basics of reading stacktraces:

  • Skim from top to bottom.
  • Stop when you see files that you wrote/recognize, and find the edge between files that are in your control and files that are out of your control.
  • Work from there outwards until you identify the problem.

Devel::Local

At SocialFlow.com we have a lot of internal perl distributions. We use Dist::Zilla to manage releasing our distributions to our internal (mini)CPAN, and we use Devel::Local to help us manage our PERL5LIB when developing multiple distributions at once.

SYNOPSIS

$ source $( which devel-local.sh ) #in my ~/.bashrc
$ cd SF-Reporting-Schema/
$ devel-local .
PERL5LIB:
/home/skaufman/dev/sf/pl/SF-Reporting-Schema/lib
|
/home/skaufman/perl5/lib/perl5
#trimmed out some stuffs
#hack hack hack.....
$ cd ../SF-Web-Schema/
$ devel-local .
PERL5LIB:
/home/skaufman/dev/sf/pl/SF-Reporting-Schema/lib
/home/skaufman/dev/sf/pl/SF-Web-Schema/lib
|
/home/skaufman/perl5/lib/perl5
$ perl script/thing_that_relies_on_changes_in_reporting_schema.pl

Now both distros lib/ directories are in our perl path, and I can work on files in both spots. This allows us to keep our distributions separated yet work on them like they're all chucked into the same lib/.

Reply

Reply Reply is a great interactive perl shell ( REPL ). It's got some of extremely useful features that I had thought unique to ipython ( a really good python repl ):

  • Tab completion
  • ctrl-r history search

You won't get all the features of Reply out of the box; installing Term::ReadLine::Gnu will get you up and running with tab completion of packages, methods, and rest of these.

All together now

Devel::Local and Devel::SimpleTrace help you manage two of the most difficult/annoying parts of library development, pathing and debugging. Effectively dealing with these issues makes you a better developer. Reply is my scratchpad; letting me test out various ideas or try to remember how to get the last index of an arrayref member of a hashref. Without my tools, I'd be a slower, stupider person. It wasn't so long ago I was staring at a white screen trying to guess why www.mystupidwebsite.com/index.php wasn't working. I had no idea where the log file was; my only trick was to smack it until it works.

Postgres full-text search w/ DBIX::Class

How to pass in a search term to postgres using DBIX::Class while still leveraging bind values to escape your input:

my $search_phrase = "snowden nsa";
my @rows = $rs->search(\[
  'to_tsvector(me.title) @@ plainto_tsquery( ? )',
  $search_phrase
])->all;

As is always the case with SQL::Abstract, TIMTOWTDI. In this case I don't particularly love the ArrayRef instead of the traditional HashRef, but that is how the cookbook had it, and it works. If anyone has a better method please leave it in the comments.

Adapt…

Resolving non-perl dependencies for perl modules in Debian/Ubuntu

One of the things developers often struggle with is dependency resolution.

For example:


cpanm WWW::Curl::Easy -v

.....

Configuring WWW-Curl-4.15 ... Locating required external dependency bin:curl-config... missing.

Unresolvable missing external dependency.

Please install 'curl-config' seperately and try again.

NA: Unable to build distribution on this platform.

This used to set me on a wild google chase, nowadays I just go to:

http://www.debian.org/distrib/packages#search_contents

or http://packag…

Arrow Operator Shenanigans

Out of curiosity, boredom, and some inspiration by the method abuse in Safe::Isa and Object::Remote, I tried the following:

use strict;
use warnings FATAL => 'all';
use feature 'say';

my $split = sub {
    my ( $str, $sep ) = @_;
    return [ split( $sep, $str ) ];
};

my $join = sub {
    my( $arr, $sep ) = @_;
    return join($sep,@$arr);
};

say "Lorem ipsum dolor sit amet"->$split(" ")->$join(":");

my $inc = sub {
    $_[0]++;
};

my $num = 4;
$num->$inc;
$num->$inc;
say $num;

I was mildly surprised that it worked. I was more surprised that I couldn't find a reason for why it worked in the documentation for the Arrow Operator.

edit [ In the comments I was pointed to perldoc perlobj where this behavior is documented. ]

I'm certain coding this way would be a Pretty Bad Idea ( especially as an undocumented language feature ) but it has a sort of appeal; though 70% of the appeal is just the sheer hackery of it with the rest being some theory that chaining may be easier to read than g(f(x)).

Update dist.ini with the versions you have installed

My usual behavior for setting version requirements in dist.ini:

Go through each dep, search for it on CPAN, copy and paste the version number.

I decided that
a) that takes too long
b) That's not the versions I've been testing with.

So I hacked this together: dzil_myversions.pl

Synopsis

$ dzil listdeps | ~/dotfiles/home_bin/dzil_myversions.pl 
aliased = 0.31
Compress::Raw::Zlib = 2.062
Data::Dumper::Concise = 2.020
Encode = 2.54
Ext…