Crib Sheet Archives

Making local::lib real easy to use

In bash, at least.

Just paste this (on your command line or into .bashrc or wherever else you want):

perl-lib() { eval "`perl -M'local::lib @ARGV' - "$@" 0<&-`" ; }

Then you can just say things like this:

$ perl-lib ~/locallib/foo
$ perl-lib --deactivate ~/locallib/bar
$ perl-lib --deactivate-all

… instead of having to type stuff like this:

$ eval "`perl -Mlocal::lib - --deactivate ~/locallib/bar`"

… or even, as you would have had to in old versions of local::lib, this awfulness:

$ eval "`perl -Mlocal::lib=--deactivate,$HOME/locallib/bar`"

Note that the shell function will work irrespective of local::lib version.

Update: I originally posted this with a 1<&- redirect in the function, which closes STDOUT. What I actually wanted to do was close STDIN, of course.

Running plenv 𝘢𝘯𝘥 perlbrew

So I just went to investigate switching from perlbrew to plenv.

This has failed before, because I run an old and grungy installation of Perl where I didn’t set up a local lib and just installed whatever without keeping records of which installed modules I need and which are just junk I tried for a few minutes. Unless I carry forward all that junk, I can’t switch perls without breaking all my local scripts – and I have better things to do.

Eventually I want to fix this situation, but no today on which it comes up has been the day for it so far.

Still, I do want to upgrade to 5.22 now that it’s out, and I’ve been wanting to switch to plenv for a while. What to do?

Uhm… *looks around*
ln -s ~/perl5/perlbrew/perls/perl-5.16.1 .plenv/versions/5.16.1
La la la… *walks away*

Yup, plenv global 5.16.1 is fine with that and a plenv rehash later, it works.

I threw out the rest of perlbrew, just kept the directory tree for the linked perl installation, and now I happily run this bastard/cuckoo setup. Teehee.

Now for installing 5.22 and making all my stuff work with it…

Serializers for Perl: when to use what

This is a moderately edited (primarily rearranged) version of a comment on the Perl 5 issue tracker written by Yves Orton (demerphq). I thought it would be useful to a wider audience so I am reposting here with permission.

Note: this was written off the cuff and is not comprehensive. In correspondence, Yves noted that such an article could/should cover more formats, e.g. MsgPack.

I [feel strongly] that Data::Dumper is generally unsuitable as a serialization tool. The reasons are as follows:

Speaker for the dead

I just retired one of my modules. I want to make a note here of the preservational ritual I followed, to invite others to consider doing the same:

Installing Term::ReadLine::Gnu on OS X, the easy way

If you try to install Term::ReadLine::Gnu on Mac OS X, you will ordinarily run into this unpleasantry from the Makefile.PL (which will likely end up in such as ~/.cpanm/build.log):

The libreadline you are using is the libedit library. Use the GNU Readline Library.

Here I will assume that you are using Homebrew and have installed GNU Readline:

brew install readline

Even so, you will get this error. This is because of how Homebrew installs Readline. Since OS X ships libedit as libreadline, Homebrew tries to avoid conflicts with system software by installing Readline as “keg-only” software – that is, it’ll install it within its package-managed filesystem hierarchy beneath /usr/local/Cellar, but it won’t link the libraries into /usr/local/lib, so that they won’t be visible to software that isn’t explicitly linked against it.

There is an easy and obvious way around this:

brew link --force readline
cpanm Term::ReadLine::Gnu
brew unlink readline

This makes Homebrew link the shared libraries into /usr/local/lib – which Homebrew ordinarily refuses to do for packages marked keg-only, like Readline is, hence the scary --force. Of course, all said and done, we unlink the package again straight away, so as to not cause conflicts. By doing this, Makefile.PL run from cpanm picks them up to link. We can confirm this:

otool -L ~/perl5/perlbrew/perls/**/Term/ReadLine/Gnu/Gnu.bundle

Its output should include something like the following line:

/usr/local/opt/readline/lib/libreadline.6.2.dylib (compatibility version 6.0.0, current version 6.2.0)

This /usr/local/opt is another Homebrew-ism:

$ ls -l /usr/local/opt/readline
lrwxr-xr-x  1 user  admin  24 14 Jul 04:53 /usr/local/opt/readline@ -> ../Cellar/readline/6.2.4

Note well that I actually have Readline 6.2.4 installed!

$ brew info readline | head -1
readline: stable 6.2.4

That means doing it this way is not only easier than the hard way found elsewhere on the web (here or there), it even allows me to brew upgrade readline without breaking Term::ReadLine::Gnu.

Making DBI’s type info data usable for its quote method

I’m putting this here mostly as future copy-paste fodder:

my %sql_type = do {
    my $ti = $dbh->type_info_all;
    my $tidx = shift @$ti;
    my ( $n, $t ) = @$tidx{qw( TYPE_NAME SQL_DATATYPE )};
    map {; uc $_->[$n], $_->[$t] } @$ti;

Now you can say things like $dbh->quote( $latitude, $sql_type{'DOUBLE'} ). This is useful in situations where you cannot use placeholders, e.g. when generating some kind of fixture.sql file from CSV data.

A little “state” idiom

    # ... something that needs to be done twice ...

    if ( not state $first_iteration_done++ ) {
        # ... something that must only happen after the first time ...

In general, some form of “if state $flag” can be used as a “have I been here?” idiom that avoids the need to mention the flag’s identifier anywhere else. Without state, one must repeat oneself some distance away at least to declare the flag in whichever outer scope has the appropriate lifetime.

A concise forking idiom in pure Perl

One of the first module I took over as a maintainer on CPAN was Proc::Fork.

It is a beautiful interface.

It did get a bit uglier in relatively recent times when I added the run_fork wrapper, an unfortunate necessity in certain cases.

But for small single-file-redistributable programs that can be offered to people who are merely users of a Unix system, who do not have any sort of CPAN setup or installation experience, it always felt like a burden to pull in a dependency for something as… insubstantial as this little bit of syntactic sugar:

run_fork {
    child {
        # ...
    parent {
        my $kid = shift;
        # ...

Just the other day, it occurred to me that with given/when, it is easy to construct an idiom for forking that is just as concise, if not self-documenting to the same extent:

Some nifty things you can do with Catalyst on Plack

Catalyst 5.9 is coming up, and the big change is a wholesale switch to PSGI, completely dropping Catalyst’s own engine system (outside of compatibility shims). This is bound to bring in new people wondering what PSGI and Plack are all about and what you can do with them.

I’ve been using Catalyst on top of Plack for a while now (with the aid of Catalyst::Engine::PSGI) and have gotten around to some nifty things with it. So here is my app.psgi for inspiration:

About Aristotle

user-pic Waxing philosophical