Orderly JSON
Orderly JSON is to JSON schema what RelaxNG is to XML Schema. This orderly:
object {
string name;
string description?;
string homepage /^http:/;
integer {1500,3000} invented;
}*;
… describes this JSON:
{
"name": "orderly",
"description": "A schema language for JSON",
"homepage": "http://orderly-json.org",
"invented": 2009
}
… and compiles into JSON schema:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string",
"optional": true
},
"homepage": {
"type": "string",
"pattern": "^http:"
},
"invented": {
"type": "integer",
"minimum": 1500,
"maximum": 3000
}
},
"additionalProperties": true
}
respondTo jQuery plugin
respondTo is a jQuery plugin that allows you to supply handlers for different AJAX response content types. In practice, it looks something like this:
$.respondTo({
url: '/people/37',
html: function(html, status) {
// handle HTML response
},
json: function(json, status) {
// handle JSON response
}
});
The naming bothers me (it looks like it’s adding a route listener instead of making an AJAX request), but it looks pretty useful. The library can also override the existing jQuery AJAX methods, if desired.
CoffeeScript
☕ CoffeeScript is a neat language that compiles down to JavaScript. The best part is that (unlike another language I’m thinking of) the resulting code is easily usable from normal JavaScript. It’s really just a layer of syntactic sugar on top of the base language.
However, there are some major differences:
:can optionally be used for assignment, instead of=. On one hand this is nice, as it unifies JSON syntax and normal language syntax. On the other, it feels really, really weird, and makes it harder to see when you’re looking at an object literal vs. normal code.- No
varkeyword, scoping is automatic. - No
functionkeyword, functions look more like Python lambdas:
// coffeescript
square: x => x * x
// resulting javascript
var square = function square(x) {
return x * x;
};
- Significant whitespace for scopes, a la Python.
Some of my favorite features:
Tail conditionals
// coffeescript
number = -42 if opposite_day
// resulting javascript
if (opposite_day) {
number = -42;
}
Comprehensions
// coffeescript
lunch: eat(food) for food in ['toast', 'cheese', 'wine']
// resulting javascript
var __a, __b, __c, __d, food, lunch;
lunch = (function() {
__a = ['toast', 'cheese', 'wine'];
__c = [];
for (__b in __a) {
if (__a.hasOwnProperty(__b)) {
food = __a[__b];
__d = eat(food);
__c.push(__d);
}
}
return __c;
})();
Inheritance and super
// coffeescript
Animal: =>
Animal.prototype.move: meters =>
alert(this.name + " moved " + meters + "m.")
Snake: name => this.name: name
Snake extends Animal
Snake.prototype.move: =>
alert("Slithering...")
super(5)
// resulting javascript
var Animal, Snake;
Animal = function Animal() {
};
Animal.prototype.move = function move(meters) {
return alert(this.name + " moved " + meters + "m.");
};
Snake = function Snake(name) {
return this.name = name;
};
Snake.__superClass__ = Animal.prototype;
Snake.prototype = new Animal();
Snake.prototype.constructor = Snake;
Snake.prototype.move = function move() {
alert("Slithering...");
return Snake.__superClass__.move.call(this, 5);
};
Multiline strings
// coffeescript
moby_dick = "Call me Ishmael. Some years ago --
never mind how long precisely -- having little
or no money in my purse, and nothing particular
to interest me on shore, I thought I would sail
about a little and see the watery part of the
world..."
// resulting javascript
var moby_dick;
moby_dick = "Call me Ishmael. Some years ago -- \
never mind how long precisely -- having little \
or no money in my purse, and nothing particular \
to interest me on shore, I thought I would sail \
about a little and see the watery part of the \
world...";
There’s even an Underscore.coffee, a full port of Underscore.js to CoffeeScript! Awesome.
PHP functions as lazy variables
Along with finally giving us anonymous functions, PHP 5.3 also gave us namespaces. This has been a looong time coming for PHP. Finally we can develop without polluting the global namespace! Or can we?
As it turns out, PHP namespaces only apply to classes, constants, and functions. Which means this:
namespace foo;
$bar = 1;
… sets $GLOBALS['bar'] to 1 across all namespaces, instead of just locally to foo. Sigh.
I’ve been playing with different idioms to get around this. First I tried static class variables:
namespace foo;
class data {
static $bar = 1;
}
// in another namespace
echo foo\data::$bar;
That’s pretty fugly. I don’t like having to lowercase a class name, but it would be even uglier as foo\Data::$bar. The biggest problem with this is that I also want to do this:
namespace foo;
class data {
static $bar = new Bar();
}
But property initializers suck in PHP, and don’t allow complex expressions. I don’t want to start adding initializer logic to the class or at the module level, so that method is out.
I ended up going with:
namespace foo;
function bar($newBar=null) {
static $bar;
if (!isset($bar) || isset($newBar))
$bar = $newBar ?: new Bar();
return $bar;
}
// in another namespace
echo foo\bar()->baz;
It also allows you to pass in a new value manually, if needed. This comes in useful for unit testing:
foo\bar(new MockBar());
I think that’s about as simple as you can get it. Bonus points: your namespace properties are now lazy loaded. new Bar() isn’t executed until the first time you call the function. If you never call it, no overhead.