Currying patterns

One of the most dangerous books I’ve ever even partially read is MJD’s Higher Order Perl. In particular, its description of subroutine currying — that is, building more specific functions out of more general purpose ones — is a pattern I find incredibly useful.

The other day I found myself writing a number of routines that were surprisingly similar… kinda. They all implemented a common pattern, but across routines that were rather… different. I found myself wistfully longing for the familiar pattern of currying, and then realized — I’m working in PERL, DAMNIT.

This is part of recent work of mine, extending Test::Moose::More to use subtests where they make sense. Here I was able to curry one function — _validate_subtest_wrapper() — by passing it a reference to another function, that it then invokes.

Excellent. Life is easier, as it should be.

easy command-line compiz settings import and export

One thing I dislike about setting up any new machine is how many places I have to poke compiz to get it to behave in the manner to which I am accustomed (e.g. widget layer enabled; sloppy focus (the One True Focus); viewport grid with names and quick-jump hotkeys; etc, etc). One can use compiz-settings-manager to do a manual import of settings (that one has hopefully exported — also manually — from another machine setup the way one likes it), but that gets… tedious.

Enter this nifty little question and answer! Note that there are two scripts: one for export and one for import.

Using these scripts to set up a cron-driven auto backup is left as an exercise for the reader. :)

Intel 7260AC Bluetooth [8087:07dc], Ubuntu, and the Thinkpad T440p

This requires a little magic, unfortunately; either the driver, system, hardware itself, or some combination thereof do not operate well with autosuspend enabled. Disabling autosuspend for this device does appear to resolve dropped / corrupted / weird bluetooth issues.

Based on my googling, I do not believe this to be Thinkpad-specific, rather something the Intel 7260AC firmware isn’t handling properly at the moment. FWIW, I’m running Ubuntu 13.10 (saucy) on the thinkpad in question, and 12.04LTS (precise) on my destop, with the same card sold by Intel in a PCI-e mount.

Based on one posting in particular, the following solution presents itself:

This isn’t ideal — as it should Just Work — but it works, and is certainly less drastic than turning off USB autosuspend globally. In retrospect, having the bluetooth device drop out shortly after boot/resume, but always be available after resuming, was a big clue.

docker without password prompting

Just a little snippet.  This should be pretty obvious to those familiar with how sudo functions, but it’s easy to run docker commands with sudo without being prompted for your password by configuring sudo to not ask for it.

Note that the normal warnings and red flags apply here.

If you install the above as /etc/sudoers.d/docker, then the user rsrchboy (line 1) and any user in the docker group (line 2) will not be asked for a password when running “sudo docker …”.

Again, the normal warnings and red flags apply here.

Useful git defaults — systemwide

Sometimes it’s necessary to — for one’s sanity, if nothing else — to establish a set of generally non-controversial, sane, system-wide git configuration defaults. This is largely helpful when multiple people are using the same system who may not have a standard ~/.gitconfig they carry around with them.

To do this, we can leverage the little-used system-wide git config file at /etc/gitconfig. Remember that by default git looks at three files to determine its configuration: /etc/gitconfig (system), ~/.gitconfig (user aka global), and .git/config (configuration for the current repository); settings closer to the user win. This allows us to set defaults in the system configuration file without interfering with people who prefer different settings: their global config at ~/.gitconfig will win.

This config sets a couple safer defaults for pushing, makes git merge/diff/rebase a little more DWIM, causes the committer, as well as the author, information to be displayed by default, as well as allowing for an easy way to override the system config on a per-system basis. (In case, say, you’re using puppet or the like to distribute this configuration across multiple hosts.)

And… As with all things “generally non-controversial”, remember that these are the sorts of things likely to touch off religious wars. The goal here is for a sane set of defaults for all users, not The One True Way To Do GIT. That’s what user global configs are for :)

screen, vim, tabs, and C-PgUp/C-PgDn mappings

I use screen with vim. One of the things I like about vim is that, much like unix itself, I’m always discovering useful new features, even after years of use.

Recently, I’ve been using tabs in vim to complement window regions. I’ve found it pretty useful, as there are times I’d want to keep certain tasks on one tab but not another. e.g. different source files open in windows on one tab; a test file + vim-pipe buffer showing the rest.

While I’m not using screen to change between multiple vim sessions in the same project anymore, I still use it pretty much everywhere: it’s there, and sometimes a wireless network isn’t. (Or you’re working one place and need to pack up and move to another place.) screen preserves your working sessions, so you don’t have to get everything “just right” again.

Unfortunately, screen seems to mangle the C-PgUp and C-PgDn commands vim gives as default (right?) shortcuts to switch between tabs. Leaving out that these key sequences are also used at the windowing level to switch tabs, it turns out that screen was mangling them on the way through to vim, so vim didn’t see C-PgUp, for instance, it saw some other sequence.

Adding this to your ~/.vimrc will cause vim to recognize the sequence it sees when running under screen:

My first YAPC::NA!

I’m in lovely Madison, WI right now, and will be headed over to my first YAPC::NA tomorrow. The first couple days are the hackathon, at which I think I’m going to work on a Dist::Zilla stash to hold repository related information. There are a bunch of Git related plugins for Dist::Zilla, a couple that I maintain, and a lot of code is duplicated between them; a stash should resolve that.

I hope to meet you all there! :)

Cheap caching with AutoDestruct

I’ve seen a couple references lately to using lazy attributes as a form of caching.  This is a great approach to thinking about lazy attributes, as they share a number of characteristics with traditional caching: you only have to build a (potentially) expensive value once, and then only when you actually need it.

But what about when that lazily generated value is too old to trust?

A lazy attribute isn’t going to help you much then, as your instance is quite happy to keep on returning the same value forever once it has been built, unless you clear or change it manually.  This is no good when, say, you’ve run a database query and you can really only expect your painfully contorted query to get the twitter ids of all the left handed Justin Beiber fans north of the Mason-Dixon line who own hypo-allergenic cats to be valid for, oh, say 55 minutes or so.

You could add an attribute to store the age of the value generated for the lazy attribute and check it either manually (boring!), or by wrapping the reader method (less boring, but still, unsightly).

Ok, method modifiers can be fun, but still…  That’s a lot of annoying little code that, well, isn’t Moose there to help reduce that sort of code in our lives?

What we’re running into here is that while we implement one part of a cache (generate once, return many), lazy attributes don’t have any internal logic to determine when a value is no longer good.  They don’t even have any concept of that, just “someone needed my value, so we’re going to get it and hang on to it until told otherwise”.

This is just the sort of behaviour an attribute trait can alter.

The AutoDestruct Moose attribute trait allows us to specify an expiration date for our stored values.  We can specify a time-to-live option at attribute creation, and then every time a value is set, the set time is stored.  Every time the value is accessed, the attribute checks to make sure the value isn’t older than the set time to live, and if it is, clears the value.  This allows the lazy value generation to kick in once more, without requiring any extra effort on the part of the user — just as one would expect.