Perl Archives

perlbrew on OSX

I’ve tried and failed so many times to use perlbrew on OSX.

I’ll admit that I haven’t started a full-on investigation, but this is really quite frustrating and confusing:

➔ perlbrew install perl-5.20.0
Fetching perl 5.20.0 as /Users/c.wright/perl5/perlbrew/dists/perl-5.20.0.tar.bz2
Download http://www.cpan.org/src/5.0/perl-5.20.0.tar.bz2 to /Users/c.wright/perl5/perlbrew/dists/perl-5.20.0.tar.bz2
Installing /Users/c.wright/perl5/perlbrew/build/perl-5.20.0 into ~/perl5/perlbrew/perls/perl-5.20.0

This could take a while. You can run the following command on another shell to track the status:

  tail -f ~/perl5/perlbrew/build.perl-5.20.0.log

perl-5.20.0 is successfully installed.

➔ perlbrew switch perl-5.20.0
➔ which perl
/Users/c.wright/perl5/perlbrew/perls/perl-5.20.0/bin/perl

➔ perlbrew install-cpanm

cpanm is installed to

    /Users/c.wright/perl5/perlbrew/bin/cpanm

➔ cpanm MP3::Info
--> Working on MP3::Info
Fetching http://cpanmirror.wtf.nap/authors/id/D/DA/DANIEL/MP3-Info-1.24.tar.gz ... OK
Configuring MP3-Info-1.24 ... OK
Building and testing MP3-Info-1.24 ... OK
Successfully installed MP3-Info-1.24
1 distribution installed

➔ perl -MMP3::Info -e1
Can't locate MP3/Info.pm in @INC (you may need to install the MP3::Info module) (@INC contains: /Users/c.wright/perl5/perlbrew/perls/perl-5.20.0/lib/site_perl/5.20.0/darwin-2level /Users/c.wright/perl5/perlbrew/perls/perl-5.20.0/lib/site_perl/5.20.0 /Users/c.wright/perl5/perlbrew/perls/perl-5.20.0/lib/5.20.0/darwin-2level /Users/c.wright/perl5/perlbrew/perls/perl-5.20.0/lib/5.20.0 .).
BEGIN failed--compilation aborted.

➔ /Users/c.wright/perl5/perlbrew/bin/cpanm MP3::Info
MP3::Info is up to date. (1.24)

sigh

IRC notifications on your phone (or Pebble watch)

IMG_20131010_202348~01.jpg

Installation

Install irssi

sudo apt-get install irssi

Grab the script:

mkdir -p $HOME/development
cd $HOME/development
git clone https://github.com/chiselwright/irc-notifications.git
cd irc-notifications

Make sure you have required perl modules available

perl Makefile.PL

Install any missing modules. (TODO: make irssi scripts work with perlbrew)

Install the script:

sh SETUP.sh

You should see something like:

➔ sh SETUP.sh
mkdir: created directory `/home/chisel/.irssi'
mkdir: created directory `/home/chisel/.irssi/scripts'
mkdir: created directory `/home/chisel/.irssi/scripts/autorun'

If you now run

irssi

you should see something like this (assuming you have an out of the box installation, with no configuration of your own yet):

19:03 -!- Irssi: irc_appnotify 0.08 ready

Any errors means some investigation into what didn’t quite work in the setup.

At this point you’ve got irssi installed and the notification plugin ready to go. Almost.

Configure PushOver

Download the relevant app for your device from https://pushover.net/clients. [NOT FREE].

SIgn up at https://pushover.net/. Copy your user key from your dashboard.

/set notify_pushover_user_key YOUR_USER_KEY
/set notify_methods Pushover
/save

Connect to a server

Store network info for future ease:

/NETWORK ADD perlOrg
/SERVER ADD -auto -network perlOrg irc.perl.org 6667
/save

Connect, set a nickname:

/connect perlOrg
/nick myTestNick

Send yourself a test message:

/q myTestNick Hello

Check your device for a PushOver alert.

Screenshot_2013-10-10-20-33-00~01.png

Get alerts on your Pebble watch

I’m assuming you’re already the proud owner of a Pebble watch.

Screenshot_2013-10-10-20-20-48~01.png

Open the Pushover preferences, tick “Display notifications on Pebble”. Sorted!

/q myTestNick Welcome to the future!

… and look at your watch.

Converting to Dist::Zilla

I’ve converted a number of distributions from $something to Dist::Zilla for release management, and every time I forget something … so this time I’m making notes as I go along.

Worst case, future-me will thank present-me (or will that be past-me?)

What follows is the transition for WebService::NotifyMyAndroid. It might have a couple of places where common sense needs to be applied, but it’s ‘good enough’.

Prerequisites

I’m assuming you’ve already got a perl distribution and that you’re managing it with git.

I’m also asssuming you already have Dist::Zilla installed.

Custom dist.ini

My distributions are minted using this file as a template for dist.ini.

Let’s Go!

Just to be safe we’ll work from anew branch based on our current master:

git checkout master
git pull --rebase
git co -b dzil master

Now we’re ready to rock and roll!

Create our dist.ini

I’m ‘lazy’ and don’t like to write mine by hand, so I’ll let Dist::Zilla do the work for me:

dzil new WebService::NotifyMyAndroid
mv WebService-NotifyMyAndroid/dist.ini .
rm -rf WebService-NotifyMyAndroid/
git add dist.ini

If you don’t already have it, it’s worth adding

[AutoPrereqs]

to your dist.ini.

Make the build process happy

To make ‘CheckChangesHasContent’ happy add the following before the most recent release:

{{$NEXT}}
      Convert to Dist::Zilla

then add it to the staged area:

git add Changes

Cleanup some files

Get rid of the files that we used to manage ourselves manually:

dzil build --notgz 2>&1 |grep 'multiple times' |cut -d' ' -f 5

If you don’t get any output at all it’s worth re-running without the piped-cut to make sure it didn’t abort the build earlier than expected.

The output should look something like this:

MANIFEST
META.yml
README
Makefile.PL

Checking the files, all the files, bar README, are autogenerated. Looking at the README we decide we’d like to keep this file, but under a different name:

git mv README README.install

Then remove the other files:

for f in $( \
  dzil build --notgz 2>&1 \
    |grep 'multiple times' \
    |cut -d' ' -f 5 \
); do
    # make sure we don't git manage them
    git rm -f $f;
    # make sure they aren't artifacts form previous builds
    rm -f $f;
done;

We also no longer need these files:

rm -rf blib/ _build/
git rm Build.PL
rm -rf blib/ _build/ Build

Nor do we want any META files hanging around:

for f in MANIFEST* *META*; do
   git rm -f $f 2>/dev/null; \
   rm -f $f; \
done

Dist::Zilla generates build directories and files based on our dist name; let’s ignore them:

echo '/WebService-NotifyMyAndroid*tar.gz' >> .gitignore
echo '/WebService-NotifyMyAndroid*/' >> .gitignore
echo '/.build/' >> .gitignore
git add .gitignore

Deal with versioning

Anywhere we’ve manually specified $VERSION we should simple remove it:

# remove manual version setting in thse files
vim $(/bin/grep -rl 'our $VERSION' lib/)
# git status
# git add <files we edited>

Add missing abstracts

To list files with missing abstracts simple do he following:

dzil build --notgz |grep "couldn't find abstract" |cut -d' ' -f 7

You should edit these manually and add an appropriate:

# ABSTRACT: <one line abstract>

line to each of the files. I prefer to put my comment at the end of the file (but before the END marker:

1;# Magic true value required at end of module
# ABSTRACT: Perl interface to Notify My Android web API
__END__

Don’t forget to ‘git add’ any files you’ve edited.

Cleanup POD

Assuming you also use the PodWeaver plugin, you should work through all the perl and POD files in your distribution to make the following alterations:

Module NAME and abstract line

No need to add the NAME section:

=head1 NAME

WebService::NotifyMyAndroid - Perl interface to Notify My Android web API

Version numbers in POD

No need to manually specify and update the VERSION block:

=head1 VERSION

This document describes WebService::NotifyMyAndroid version 0.0.3.

Licence and Copyright

This is added automatically, so you can remove any of these sections

Authors and Contributors

In lieu of a ‘Contributor plugin’ you may wish to promote your contributors to authors - otherwise you end up with them in different parts of the woven POD.

Make sure you specify your authors in dist.ini:

author           = Steve Huff <shuff@cpan.org>
author           = Chisel <chisel@chizography.net>

and remove any ‘AUTHOR’ and ‘CONTRIBUTOR’ sections in your POD.

Custom step

I did this just for this distro, just to cleanup:

git rm README.mkd

Commit And Push

We’re in the final stages now; time to push our work to our remote to keep it safe:

git commit -m 'Convert dist to use Dist::Zilla'
git push -u origin master

Test a release candidate

From my experience, you’ll always miss something obvious, or silly when converting to Dist::Zilla, so it’s probably best to release a developer release of the module until there’s enough feedback from CPAN Testers for us to fix everything, or decide it’s good enought to release to the world:

dzil clean && \
V=0.0.5_01 dzil release

Keep Testing

If you’re anything like me, you’ll miss a few things on your first release, no matter how careful you are. You’ll also probably find you get failures for unexpected and surprising reasons.

Don’t despair, just chip away at the niggles until you have a developer release that shows as a pass for all (or near enough) reports on CPAN Testers.

Versioning Developer Releases

I finally stopped to think about how I’m numbering my developer releases for various modules I have floating around.

Two theories

Until recently I’ve always thought:

v0.0.5_1 is the first developer release leading up to v0.0.5

Something (sorry, I can’t remember what exactly) I read recently got me thinking about this and I started to think that maybe I’d got myself tied up into knots.

I started to wonder if the correct interpretation was actually:

v0.0.5_1 is the first developer release AFTER v0.0.5; working towards v0.0.6

I’m sure this is blindingly obvious to some people, but it was something I’d never stopped to properly thing about.

Investigation

After writing a quick script I came up with the following output:

.-------------+-------------+-------------+---------------.
| Input       | normal()    | cmp-prev    | cmp-next      |
+-------------+-------------+-------------+---------------+
| 0.0.4       | v0.0.4      |             | <  0.0.5      |
| 0.0.5       | v0.0.5      |  > 0.0.4    | <  0.0.5_01   |
| 0.0.5_01    | v0.0.5_1    |  > 0.0.5    | <  0.0.5_50   |
| 0.0.5_50    | v0.0.5_50   |  > 0.0.5_01 | <  0.0.5_99   |
| 0.0.5_99    | v0.0.5_99   |  > 0.0.5_50 |  > 0.0.5      |
| 0.0.5       | v0.0.5      | <  0.0.5_99 | <  0.0.6      |
| 0.0.6       | v0.0.6      |  > 0.0.5    |               |
'-------------+-------------+-------------+---------------'

Conclusion

As you can see, the non-developer release numbers compare as expected.

0.0.5 was put before and after the 0.0.5_xx versions for comparison at both ends.

As you can see,

v0.0.5 is less than < 0.0.5_01

and

v0.0.5_1 is greater than v0.0.5

This matches my newer, second hypothesis:

v0.0.5_1 is the first developer release AFTER v0.0.5; working towards v0.0.6

Why does this matter?

For the most part, most people really won’t care … or even notice. I’ve been getting this wrong for as long as I can remember and haven’t been adversely affected.

However, if you want the progression of your code to ‘make sense’ with the progression of your version numbers it’s important to get this right.

Also, although untested, I’m fairly confident that if you have some poor soul brave enough to try out your v0.0.5_1 release and after a few iterations you’re happy with the results and release v0.0.5 ‘final’ you’re doing a disservice to the brave soul who’ll never ‘upgrade’ to your lower version numbered release.

Command history in the perl debugger

I’m always forgetting what pieces I need to make this happen, so I’m writing a note to my future self.

Ubuntu Packages

Install:

  • libncurses-dev
  • libreadline-dev

Perl Packages

Install:

  • Term::ReadLine::Gnu

Save a little time with puppet

Include these somewhere and run a puppet update

class libncurses-dev {
    package { libncurses-dev: ensure => latest }
}

class libreadline-dev {
    package { libreadline-dev: ensure => latest }
}

Save the history to a file

Add this to ~/.perldb

&parse_options("HistFile=$ENV{HOME}/.perldb.hist");

Notify Your Android?

Following my recent move into the World of Android I’ve been looking into notification apps that I can hook into and send message to using Perl.

Luckily for me there was already a perl module, WebService::NotifyMyAndroid, that had already done the hard work of communicating with the API at Notify My Android.

As with all thing, it hadn’t seen a release in about a year, and the sneaky NMA guys had changed all their URLs - breaking the module’s calls.

As an interested hacker I took a copy of the code and made the appropriate changes to get it up and running again.

Last night, after emailing the module’s author and having a short conversation I became co-maintainer of the module.

This morning I uploaded v0.0.3 to the CPAN.

Merry Festive Time!

DBD::Mock ... still maintained?

Has DBD::Mock fallen out of favour, love or maintainer energy?

Some recent work at $employer led to me working on a patch for some desired changed to the module.

After hunting down a likely looking repo on github, forking and sending a pull request I noticed that there was one other pull request that’s been sitting there for a year now.

Checking today it looks like the RT ticket queue for the distribution is looking equally unloved.

Is this me volunteering myself as a potential maintainer of the distro? Maybe … if that’s what it takes.

Easy Data::Printer in the perl debugger

I find myself often wanting the magic of Data::Printer when I’m debugging. Sometimes ‘x’ just doesn’t cut the mustard.

I’ve finally got bored of typing:

use Data::Printer alias => dp;

in the debugger and have taken some time to make it available automatically.

If you want to try it add the following to $HOME/.perldb:

$DB::alias{dp} = 's/dp/DB::dp/';
sub DB::dp {
    eval {
        require Data::Printer;
        Data::Printer->import(colored=>1,use_prototypes=>0);
    };
    if ($@=~/Can't locate/) {
        print 'Data::Printer is not installed';
        return;
    };
    print Data::Printer::p(@_);
}

You can test it works with the following:

perl -d -e '$DB::single=1; $a'
main::(-e:1):   $DB::single=1; $a
auto(-1)  DB<1> v
1==>    $DB::single=1; $a
  DB<1> dp { foo => bar }
{
    foo   "bar"
}
  DB<2>

(Yes, you can use ‘-e 1’, but I have NonStop=1 in my parse_options() setting)

What does CATALYST_DEBUG do?

Introduction

I used to think that CATALYST_DEBUG was an all-reaching magical environment variable that somehow affected the ‘Come back Later’ screen as well as what messages were output via $c->log->...().

I’ve educated myself since then but I’ve always thought it would be an interesting exercise explicitly exploring and documenting the various behaviour under different conditions.

The Code

Code for this example can be found in the catalyst_debug branch.

After each change we run ./script/demo_server.pl with various settings and note the results.

Basic Death

What do we see if we have an action that dies?

Edit lib/Controller/Root.pm so that the index() dies (af2a29e):

sub index :Path :Args(0) {
    my ( $self, $c ) = @_;
    die 'Shot through the heart!';
    $c->response->body( $c->welcome_message );
}
ENV variables script options Result
    Error Screen
CATALYST_DEBUG=0   Come Back Later
CATALYST_DEBUG=0 -d Error Screen
CATALYST_DEBUG=1   Error Screen

Remove ‘-Debug’ plugin

What happens if we don’t force the -Debug plugin?

Edit lib/Demo.pm and remove the -Debug Catalyst plugin (4fa87c0):

use Catalyst qw/
    ConfigLoader
    Static::Simple
/;
ENV variables script options Result
    Come Back Later
CATALYST_DEBUG=0   Come Back Later
CATALYST_DEBUG=0 -d Error Screen
CATALYST_DEBUG=1   Error Screen

Add StackTrace plugin

What happens if we want to see stack trace information on the Error Screen?

Edit lib/Demo.pm and add the StackTrace Catalyst plugin (20a6dd0):

use Catalyst qw/
    ConfigLoader
    Static::Simple
    StackTrace
/;
ENV variables script options Result
    Come Back Later
CATALYST_DEBUG=0   Come Back Later
CATALYST_DEBUG=0 -d Error Screen w/StackTrace
CATALYST_DEBUG=1   Error Screen w/StackTrace

Add ErrorCatcher plugin

What happens if we add ErrorCatcher to the mix?

Edit lib/Demo.pm and add the StackTrace Catalyst plugin (95b1fc4):

use Catalyst qw/
    ConfigLoader
    Static::Simple
    StackTrace
    ErrorCatcher
/;
ENV variables script options Result
    Come Back Later
CATALYST_DEBUG=0   Come Back Later
CATALYST_DEBUG=0 -d Error Screen w/StackTrace + console ErrorCatcher
CATALYST_DEBUG=1   Error Screen w/StackTrace + console ErrorCatcher

Test debug() with default settings

How do the variations affect logging output?

Edit lib/Controller/Root.pm and replace the death wih debugging into the log (24d7b65).

ENV variables script options Result
    Welcome Screen + console [debug]
CATALYST_DEBUG=0   Welcome Screen + console [debug]
CATALYST_DEBUG=0 -d Welcome Screen + console [debug]
CATALYST_DEBUG=1   Welcome Screen + console [debug]

Remove debug from log levels

Do any of the options add the debug log level?

Edit lib/Demo.pm and configure the log levels after calling setup() (83eb502).

ENV variables script options Result
    Welcome Screen
CATALYST_DEBUG=0   Welcome Screen
CATALYST_DEBUG=0 -d Welcome Screen
CATALYST_DEBUG=1   Welcome Screen

Conclusion

  • -Debug isn’t necessary in a Catalyst application
  • error debugging output can be controlled with either CATALYST_DEBUG or the -d script option
  • Neither CATALYST_DEBUG or the -d have any affect on the behaviour of $c->log->debug(...)

Because you may wish to run your application using alternative servers you should consider using CATALYST_DEBUG as you primary method for enabling error debugging output. If you happen to my using myapp_sewrver.pl you can export this for perma-debugging, or use the -d switch as required.

If you wish to control the logging levels for $c->log->...() don’t even consider CATALYST_DEBUG or the -d switch - you’re confusing different types of debugging.

Don’t use CATALYST_DEBUG

Throughout this experiment I’ve used CATALYST_DEBUG. Ideally you’d be a thoughtful developer and use MYAPP_DEBUG to ensure that you don’t inadvertently alter the error debugging of other Catalyst based applications in mysterious and unexpected ways.

Module Versions Used

During this experiment the following modules were used:

[Catalyst::Runtime]              5.90007
[Catalyst::Devel]                1.33
[Catalyst::Plugin::StackTrace]   0.11
[Catalyst::Plugin::ErrorCatcher] 0.0.8.10

CPAN Testers - "Can't locate FindBin/libs.pm in @INC"

Following my recent update to Catalyst::Plugin::ErrorCatcher I’ve taken some time to scan through the CPAN Testers Reports for the module.

I have to admit to being somewhat perplexed at one of the common test failures [example report]:

Can't locate FindBin/libs.pm in @INC

I’ve specified the library as a ‘TestRequires’ dependency in my Dist::Zilla dist.ini file:

[Prereqs / TestRequires]
DateTime = 0
File::Slurp = 0
FindBin::libs = 0
...

The generated Makefile.PL contains this as a ‘BUILD_REQUIRES’ dependency:

"BUILD_REQUIRES" => {
    # ...
    "File::Slurp" => 0,
    "FindBin::libs" => 0,
    "HTTP::Request::Common" => 0,
    "IO::File" => 0,
    # ...

I’ve also installed ErrorCatcher via cpanm on a perlbrew setup with FindBin::libs missing … and it was installed as a dependency.

There are so many of these reports that it can’t be one or two ‘unusual setups’ as the root cause. Either something has changed, or I’ve done something really stupid during the development of the module.

It’s slightly frustrating only being able to see the output of ‘make test’ and not anything from ‘perl Makefile.PL’.

Previous releases:

  • v0.0.8.9 has the dependency and exhibits the problem
  • v0.0.8.8 lists the dependency and does not exhibit this problem

I like to do as much as I can to resolve issues with my modules installing on various configurations but I’m not really sure where to go next with this one.

About Chisel

user-pic I blog about Perl.