cannot open shared object file: No such file or directory – …

Got this error while deploying a Rails app on Nginx: cannot open shared object file: No such file or directory - ...

This means that the ibm_db adapter is installed, but it can’t find the DB2 libraries. The issue is that IBM_DB_HOME and some other environment variables are not set.

The best solution is to make sure all users have db2profile loaded. Edit /etc/profile and add:

. /opt/dsdriver/db2profile

You should now reload your profile (. /etc/profile) and restart Nginx.

This assumes that you already have IBM Data Server Driver installed under /opt/dsdriver.

Pixel-pushing in canvas

By way of avva (Russian), I was pointed to this excellent analysis of Notch’s 4kb Javascript/Canvas demo of flying through a 3d labyrinth:

Per the Hacker News discussion, this is not necessarily the way you should be using canvas for 3d — that’s what WebGL is for — but seeing what’s possible with relatively simple code and the basic web technologies is inspiring.

(Notch is the creator of Minecraft.)

TypeScript’s doomed embrace of JavaScript

Microsoft recently announced TypeScript. From what I can tell, it’s Javascript with optional types. The type annotation syntax is the same as in Adobe’s ActionScript and in the sadly defunct ECMAScript 4.

TypeScript also includes a new class syntax based on the one proposed in ECMAScript 6. I’m dubious about the addition of class-based features to Javascript. Javascript’s traditional strength is in prototypal inheritance and informal interfaces. I think there’s value in there being only one way to do things in a programming language.

As the Zen of Python puts it:

“There should be one– and preferably only one –obvious way to do it.”

And as Ruby’s designer Matsumoto describes the Principle of Least Astonishment:

“Everyone has an individual background. Someone may come from Python, someone else may come from Perl, and they may be surprised by different aspects of the language. Then they come up to me and say, ‘I was surprised by this feature of the language, so Ruby violates the principle of least surprise.’ Wait. Wait. The principle of least surprise is not for you only. The principle of least surprise means principle of least my surprise [sic]. And it means the principle of least surprise after you learn Ruby very well. For example, I was a C++ programmer before I started designing Ruby. I programmed in C++ exclusively for two or three years. And after two years of C++ programming, it still surprises me.”

I’ve written Perl, and I’ve written C++. Both of them are kitchen sink languages that allow for every possible way of doing things. Per the above, this is not a good thing. For a discussion of the problems with C++, try the C++ Frequently Questioned Answers (FQA).

I think adding classes to Javascript would detract from the beauty of the language, or at least the beauty of JavaScript’s Good Parts. I would suggest that a much more useful and Javascript-esque enhancement would be not adding classes, but rather adding Go-style interfaces.

TypeScript is unlikely to become any more successful than Google’s Dart, thought to give Microsoft credit TypeScript is a lot more compatible with the existing Javascript infrastructure. The only post-Javascript success story that I’m aware of is CoffeeScript, and CoffeeScript’s strength is that it does not seek to replace Javascript.

(On a side note, I found out about TypeScript from Eric Lippert’s How do we ensure that method type inference terminates?)

How to access web console from Greasemonkey userscripts

Userscripts are helper Javascript programs that you can add to your browser to automate and optimize the web pages you visit. Greasemonkey is a Firefox extension to run userscripts. The web console is a tool built into Firefox and other browsers that can be helpful during userscript development.

How can you access the web console from Greasemonkey userscripts? First of all, you should not do this in production. However, logging to the web console can be a useful tool during development.

Here’s how you do it:

// Put this at the top of your userscript
var console = unsafeWindow.console;

Bonus: How to access your userscript’s jQuery from the web console

// Expose userscript's jquery to the web console
unsafeWindow.$ = $;

Again, do not do this in production.

Userscript for faster deletion of MediaWiki spam

A couple weeks ago I posted a userscript that makes banning MediaWiki spammers easier by setting good defaults for the user ban form. Since then, I’ve had to ban a lot of spammers, so I thought I should remove another point of friction.

For some reason, MediaWiki chooses to not provide direct deletion links on the User Contributions page, so after banning a spammer you have to click through to each piece of spam before deleting it. This may have been an acceptable user experience in Web 1.0 days, but it’s a ridiculous set of hoops to jump through today.

My goal is to eventually make banning a spammer and deleting all the spam they’ve posted a one-click process. If there’s an existing solution for this, I’d love to hear about it.

Since I needed to do some DOM manipulation, I chose to use jQuery in the userscript. This was also a lot easier than I might have expected. Userscripts really are a very solid technology.

// ==UserScript==
// @name           Mediawiki - Fast delete on user contributions view
// @namespace
// @description    Adds a delete link for every page on the user contributions view
// @include*
// @require
// ==/UserScript==

// Add page delete links to the user contributions page
function enhanceHistory() {
  "use strict";

  // Find the history link for each revision
  $('#bodyContent ul li')
    .each(function(i) {
      // Append a page delete link after each history link
      var url = this.toString().replace('action=history', 'action=delete');
      $('<span> | </span><a href="' + url + '">del</a>').insertAfter($(this));


I passed the above through JSHint to make sure there’s nothing silly in it, but I haven’t consulted the jQuery style guide so it may not conform to the usual formatting.

The page delete links still lead to a standard confirmation form, so this doesn’t violate the RESTful practice of only using links for reading content rather than changing it.

Here’s a screenshot of what it adds to the user interface:

Userscript to make banning MediaWiki spammers easier

Somehow, I’ve come to be responsible for administering two MediaWiki-powered wikis. The main burden is having to ban spammers, which sometimes sign up in batches of 20 at a time.

To help with process, I’ve put together the following browser userscript. On Firefox, you can easily set it up using the Greasemonkey extension. Opera and Chrome have their own facilities.

The script basically makes the default values on the user ban form sane, so I can just click through without fiddling with dropdown and checkboxes. Obviously, the ban has to be permanent. Obviously, I don’t want spammers emailing anyone.

// ==UserScript==
// @name           Blocker
// @namespace
// @include*
// ==/UserScript==

// Set default expiry to 'infinite' or 'indefinite', depending on MediaWiki version
function makeExpiryInfinite () { "use strict";
  // Get the element
  var elExpiry = document.getElementById('wpBlockExpiry');
  if (!elExpiry) { elExpiry = document.getElementById('mw-input-wpExpiry'); }

  // Abort if element not found
  if (!elExpiry || !elExpiry.children) { return; }

  // Find the infinite option
  var expiryNodes = elExpiry.children;
  var index = 0;
  for (var i in expiryNodes) {
    if (expiryNodes[i].label && expiryNodes[i].label in {infinite:1, indefinite:1}) {
      index = i;

  // Set dropdown to the infinite option
  elExpiry.selectedIndex = index;

// Automatically prevent user from sending e-mail
function preventEmail() { "use strict";
  // Find check box
  var elEmailBan = document.getElementById('wpEmailBan');
  if (!elEmailBan) { elEmailBan = document.getElementById('mw-input-wpDisableEmail'); }

  // Abort if it's not there
  if (!elEmailBan) { return; }

  // Check the box
  elEmailBan.checked = true;

// Automatically prevent user from sending e-mail
function reallyBanThatIP() { "use strict";
  // Find check box
  var elHardBlock = document.getElementById('mw-input-wpHardBlock');
  if (!elHardBlock) { elHardBlock = document.getElementById('mw-input-wpHardBlock'); }

  // Abort if it's not there
  if (!elHardBlock) { return; }

  // Check the box
  elHardBlock.checked = true;


I’ve been hearing wonderful things about userscripts for years, but this is the first one I’ve put together for myself. It’s actually very easy to write these, assuming you know Javascript and have tools like Firefox’s Web Console and the Web Developer extension handy.

I’m planning to enhance it a little so that it handles the slightly different form for banning anonymous users, but I’m not sure if it makes sense to submit to any official repository. It helps with running small wikis that have open memberships, so there isn’t any one site I can identify it with. Obviously, it’s not suited for Wikipedia, as they have a very different set of problems.

Edit: Updated the script with better handling for banning anonymous users by IP address.

setTimeout() require qualification

The two javascript functions above are very useful. The first one executes something after a set delay, and the second executes something at regular intervals. The syntax is very similar.

var time = 2000; // 2 seconds
window.setTimeout(function() { alert('Yay!'); }, time);
window.setInterval(function() { alert('Woo!'); }, time);

Unfortunately, they weren’t working for me earlier. It turns out I wasn’t fully-qualifying them. Specifically, I was calling setTimeout() rather than window.setTimeout(). The latter works.

Most examples use the abbreviated form, which consistently doesn’t work for me.

Disabling PHP in a specific directory

To disable the PHP processor in a given directory, put the following in an .htaccess file. If one doesn’t exist, create it.

# Disable PHP
AddHandler default-handler php
RemoveType application/x-httpd-php php

# Make .php files display as plain text
AddType text/plain php

This assumes an Apache server. PHP on IIS may involve different steps.

Files starting with a . are hidden by default on *nix OSes. To see them in listings, use ls -a.

ERROR: Failed to build gem native extension.

I ran into a tiny pickle while installing the ibm_db gem on Ubuntu:

Select which gem to install for your platform (i486-linux)
 1. ibm_db 0.9.5 (ruby)
 2. ibm_db 0.9.5 (mswin32)
 3. ibm_db 0.9.4 (ruby)
 4. ibm_db 0.9.4 (mswin32)
 5. Skip this gem
 6. Cancel installation
> 1
Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Gem::Installer::ExtensionBuildError)
    ERROR: Failed to build gem native extension.

ruby extconf.rb install ibm_db
extconf.rb:9:in `require': no such file to load -- mkmf (LoadError)
	from extconf.rb:9

The problem is that mkmf isn’t included in the base Ruby package on Ubuntu. You need need the full development package to install gems from source. Installing it solves the problem.

sudo apt-get install ruby1.8-dev