snapsvg

2012-08-31

Oh go on

alias please='sudo $(history 2 | head -n1 | perl -pe "s/^\s*\d+\s+//")'

Update:

alias please='sudo $(fc -nl -1)'

2012-08-30

Catalyst::Authentication::Store::MongoDB 0.02 finally released

Took me a bit of time fighting CPAN to get it to index it (that'll teach me to try to use 1e-4 as a version number) but the patches that a kindly chap in the community sent to me (wasn't sure if he wanted to be named so I have erred on the side of caution) are now up on CPAN.

This means that both you and I can finally use MongoDB for our Auth stores, and I can finally continue working on the project I was working on before this debacle put me off.

Check it out here (http://metacpan.org/module/Catalyst::Authentication::Store::MongoDB), or here (http://search.cpan.org/~altreus/Catalyst-Authentication-Store-MongoDB-0.02/lib/Catalyst/Authentication/Store/MongoDB.pm) if you prefer the old-fashioned CPAN.

The module's on github, as is everything ever, here (https://github.com/Altreus/Catalyst-Authentication-Store-MongoDB).

2012-08-06

Mars Fiction

In recognition of the momentous occasion of NASA managing to fire things at a planet and not miss I thought I'd compile a list of recommended reading/watching/listening of stories set on or featuring Mars.

This list is almost certainly going to be entirely sci-fi. Men Are From Mars, Women Are From Venus absolutely does not count.

So without further ado:

Books

  • John Carter of Mars - Edgar Rice Burroughs
  • Martian Chronicles - Ray Bradbury
  • War of the Worlds - HG Wells
  • Out of the Silent Planet - CS Lewis

TV

  • Doctor Who: The Waters of Mars
Some others have been suggested tangentially so I'll record those too.

  • Y: The Last Man - Brian K. Vaughan (Comics)
More to come!

2012-07-27

Quick jQuery empty-object test

Arrays have .length but objects don't.

But since you're already using jQuery you can simply use param() to get a truthy value for the object:

  if ($.param(obj)) {
    // obj has stuff
  }

Al out.

2012-07-23

empty() Considered Harmful

PHP has a function—which may or may not be a function—called empty().

From its docs:

A variable is considered empty if it does not exist or if its value equals FALSE. empty() does not generate a warning if the variable does not exist.


First of all let's apply a little bit of logic. If the value equals false, that means that

  empty($foo)

is exactly the same as

  $foo == FALSE

which is, in turn, exactly the same as

  ! $foo

So these expressions are identical.

Except for one small thing:

empty() does not generate a warning if the variable does not exist.

Absolutely, never ever, in the name of all that is good and holy, even consider doing something like this.

I mean, for fuck's sake, this is a language that complains if an array index doesn't exist!

One of the most basic rules in programming is that you get the compiler and runtime systems to tell you when things are wrong as much as is humanly possible. The stricter the better! Except possibly in the case of PHP, it is almost certain that the person who wrote the language you're using is smarter than you are. It is certain that your compiler (or at least your runtime machine) knows whether or not what you have written is valid. If you suppress the computer's warning that you've done something wrong then you're a fucking idiot, pardon my English.

Testing a variable for empty instead of falseness does exactly one extra thing: it suppresses one of the most useful error messages actually available in PHP, which is that you've misspelled your variable name. Why in god's name would you do that?

The Sanctity Of The Symbol


See, the variable space is sacrosanct, OK? That's essentially rule number one. When you create a variable you are performing a ritual, a rite of ascension, that brings the abstract, incorporeal idea of an item of data from your grey matter and establishes it, manifests it in a real way in the script of your program. This variable serves a purpose: it is a vessel in which you are going to put information without which your routine will surely fail! It is a transferrable, mutable mug of the elixir of the programming gods, a chalice of the very stuff of which a program's execution is made.

Ideally, to create such a vessel would require some sort of incantation, a keyword of declaration. But if you don't have one, the next best thing is to have it be a horrible, terrible crime to try to sip juice from a cup that does not exist!

But! I hear you cry. But what of the processed symbol names? What of those, collected by a prefix, whose existence allows us to enumerate a user's input, and determine whether the input is enough, or missing, or will cause us to behave differently?

I say unto thee: That's what the associative array is for you bozo. An associative array, stored in the sacrosanct variable, is an anarchic, loose, free data dump, in which one can add arbitrary keys, string symbols inherently grouped under the bosom of the variable's own name, but milling around, free radicals in the womb of the variable. To complain about the non-existence of a key in an associative array is to complain about the non-existence of the girl from the ice-cream stall in the club you happened to wander into today. It is legitimate, nay expected, that in this array some information exists and some does not.

The non-existence of a variable is fact. It is not optional. Do not test for a variable's existence. Do not avoid the penalty for accessing one. If you cannot birth your variables with a word of magic, at least do not dismiss the warnings of the almighty when it tells you that your variable is not even there.

2012-07-19

Today's PHP-induced bug: arbitrary object properties

Today's stupid bug that shouldn't happen is brought to you by PHP's retarded object system. The various systems it appears to be bastardised from are incompatible but it is mostly similar to Java's: single inheritance, interfaces and access protection.

Access protection is where today's bug comes from. As you had better already know, PHP's classes can be declared with properties:

class Foo {
    public $bar;
    protected $_foo;
    private $_baz;
}

This declares that, with an object $obj of type Foo one can access $obj->bar but not $obj->_foo or $obj->_baz without being lexically within the class (for $_baz) or a subclass (for $_bar) of Foo.

But unlike Java's slightly more robust system, PHP allows you to arbitrarily create properties on objects:

$obj->bazinga = 1;

Since bazinga is not even declared on class Foo, the correct response for any self-respecting object system would be to tell you to sod off and stop playing the fool.

Alternatively, it would not provide a way for you to declare properties on the class in the first place, because doing so is wholly inappropriate when any property not declared is implicitly available, and public.

This sort of logic is akin to the logic of the courts that ruled that ISPs must block the pirate bay, but not block any other website that shares torrents, nor any website that allows you to access the pirate bay via proxy. That is to say, it's never going to work.

The problem is of course that the point of declaring protected and private member variables on classes is twofold, like most things:

  1. The structure of the data represented by objects of this class is a defined contract. Attempting to access non-existent properties will error because the user is trying to do something that cannot be done by the contractual interface, meaning that the user is most likely mistaken as to the identity of the variable they are dealing with.
  2. The data structure of the object is usually not for public consumption and defines a state in which the object may be. The object exposes an interface by which the data values can be manipulated but the user has no control over how this manipulation takes place internally.

If you want arbitrary strings to be available as a public property on a data structure you wanted a map. This is implemented as an associative array in PHP, a hash in Perl and Ruby, and a dictionary in Python.

Point 1 of the two reasons why you don't do what PHP doesn't understand why you don't do is the reason why I wish it didn't. I had defined an interface on my class promising that any value passed to a particular method would be later returned by the same method when not passed any argument besides null:

public function value($val = null) {
    if ($val !== null) {
        $this->_value = $val;
    }

    return $this->_value;
}

A very common interface. The fact that it is implemented by storing the value in the protected property $_value is no business of the user's. The class defined no public property '$value' but, when I did this:

$obj->value = 'foo';

No complaints were raised. And yet for all such objects, nullness persisted throughout my data.

It is not simply that my class, not having declared the property 'value', had no obligations regarding such a property: the interface defined on my class had the very specific obligation to deny the property 'value' from being accessed in any way whatsoever, because that property is not a part of the data structure represented in my class.

PHP allows you to access any identifier on an object as a property, and only the subset that you explicitly declare protected will be so. The rest are first given to a special method called __get to get, or __set to set, and if they do nothing it just goes ahead and creates something for you.

I have no implicit problem with these magic get/set methods per se—the problem arrives when the default function of these methods is to allow the thing through! If the default reaction were to tell you to take a hike this whole thing would be fine. Give a class the opportunity to deal with arbitrary properties, sure; that then becomes part of the contractual interface of the object. But no contract should be so liberal as to let people crap all over them unchecked.

PHP: you are doing classes wrong.


2012-05-02

Serving a static site

Just found this. https://github.com/balupton/simple-server

Dead handy for developing a static site because it lets you use root-anchored paths in your assets, which doesn't work if you open the static pages in the browser because root is in the wrong place.

2012-04-27

PHP's date()

I wish people would stop using this crappy function. It doesn't do anything strftime can't do, but you can't put your format codes inside other strings so you always end up resorting to strftime anyway.

On top of that, if you know how to use strftime you won't have culture shock when you use literally any other language ever written.

Accuracy of exaggeration not guaranteed.

Also I don't think it's locale-aware.

2012-04-24

How to Rant About Languages

Opinions are great. They make the world go around. Everyone hates things they don't understand, unless they are intrigued, in which case they learn about it instead and then stop hating it because they don't understand it.

However, you can understand something and still hate it.

When constructing a rant, I find there is one key feature it should have that differentiates a valid complaint from an opinionated spiel: if you can replace the subject of the rant with any other subject and not introduce factual inconsistency, your rant is invalid.

Here's a rant about PHP http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/

Here's a rant about Perl http://www.schnada.de/grapt/eriknaggum-perlrant.html 1

You will see that if you replace PHP with, say Python in the first rant, the rant becomes factually incorrect. Sure, many of the principles remain true - that consistency is good, that lurching obliviously through errors is not a great idea - but the fact that Python does those things is provably false. This makes a good rant.

But if you replace Perl with Python in the second rant you will find that it is true of Python as well. And C. And PHP. And French if you care. This does not make a good rant, because it's boring, and no one can take away anything constructive from it.

Please, if you must rant, make it specific to your hated language. If one of the people who writes the compiler for that language reads it, they should be able to take away from it something that they can fix. If you can't construct a rant about actual, deniable problems with the language, then you don't know enough about the language to have an opinion in the first place.

1 Actually about PERL, that dot-com-boom all-purpose no-knowledge-required hacker language that attracted all the awful coders like flies around shit and produced some of the most godawful, buggy, unmaintainable tripe only matched by the same principles being core to PHP.

2012-01-30

Simple gnome 3 wallpaper switcher

Gnome 3 uses dconf rather than gconf, so gconf-based wallpaper switchers won't work. Luckily, the actual change is only that one line if you do it right.

I created a script that uses a cache of wallpapers. First, here's the script that searches your wallpapers directory for actual images (to filter out stupid Thumbs.db and things like that) and adds them to a file.

#!/bin/bash
find "$HOME/wallpapers" -type f \
  -exec sh -c 'file "$1" | grep -q "image"' '{}' '{}' \; \
  -a -fprint wallpapers-cache-new \
\
&& mv wallpapers-cache-new wallpapers-cache


That outputs a file called wallpapers-cache, and the wallpaper switcher itself uses that:

#!/bin/bash

WALLPAPERS="$HOME/wallpapers-cache"
export DISPLAY=:0

r=`rl -c1 $WALLPAPERS`

gsettings set org.gnome.desktop.background picture-uri "file://$r"

rl comes from the randomize-lines package in Debian-based OSes.

Add the latter to crontab to change your desktop as often as you'd like. VoilĂ !