1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
var HOST = 'localhost';
var PORT = 80;
var API = "/api/user/create";
var tobi = require('tobi'),
vows = require('vows'),
assert = require('assert');
var newbie = function() { return tobi.createBrowser(PORT, HOST) };
// -------------------------------------------------------------
// Macros.
// -------------------------------------------------------------
var macroPostOnlyApiChecks = function(url) {
return {
'GET': {
topic: function() {
var browser = newbie();
browser.get(url, this.callback);
},
'should fail.': function(res, $) {
res.should.not.have.status(200);
}
},
'Empty POST': {
topic: function() {
var browser = newbie();
browser.post(url, this.callback);
},
'should fail.': function(res, $) {
res.should.not.have.status(200);
}
}
};
};
var macroCreateUserOk = function(suite) {
return {
'Create user': {
topic: function() {
var browser = newbie();
var data = { signupUsername: '', };
data = JSON.stringify(data);
browser.post('/api/user/create', data, this.callback);
},
'should succeed.': function(res, $) {
res.should.have.status(200);
console.log(res);
// Pass created user credentials back to
// the calling suite for later use.
if (suite) {
}
}
}
};
};
// -------------------------------------------------------------
// User API Test Suite
//
// Run me with: vows api.user.create.vows.js --spec
// -------------------------------------------------------------
var suite = vows.describe('User API Test Suite');
// Batches are executed sequentially.
// Contexts are executed in parallel.
suite.addBatch(macroPostOnlyApiChecks(API));
suite.addBatch(macroCreateUserOk());
suite.export(module);
|
Decorators In C
Turns out you can also do decorators in C, this came in handy for something else I had to work on recently. It’s not quite as nice, because functions aren’t first-class, but handy nonetheless.
Here’s what that looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#include <stdio.h>
typedef int (* const decorableFnType)(int paramOne, int paramTwo);
int functionOne(int paramOne, int paramTwo)
{
printf("functionOne: %d, %dn", paramOne, paramTwo);
return 0;
}
int functionTwo(int paramOne, int paramTwo)
{
printf("functionTwo: %d, %dn", paramOne, paramTwo);
return 0;
}
int functionThree(int paramOne, int paramTwo)
{
printf("functionThree: %d, %dn", paramOne, paramTwo);
return 0;
}
int decorator(int paramOne, int paramTwo, decorableFnType originalFn)
{
printf("decorator precondition!n");
originalFn(paramOne, paramTwo);
return 0;
}
int main(int argc, char **argv)
{
printf("hello, C decorators!n");
functionOne(1, 2);
decorator(1, 2, functionOne);
decorator(1, 2, functionTwo);
decorator(1, 2, functionThree);
return 0;
}
|
The output of which is:
vilimpoc@funky:~$ ./c-decorators
hello, C decorators!
functionOne: 1, 2
decorator precondition!
functionOne: 1, 2
decorator precondition!
functionTwo: 1, 2
decorator precondition!
functionThree: 1, 2
vilimpoc@funky:~$
This might be a bit simplistic, in reality, you’d probably want to decorate a function with a signature like the following, so that you can just change the structure and not bother w/a bajillion function declarations:
1 |
typedef int (* const decorableFnType)(SomeStruct * data);
|
Again, not super elegant, but handy.
Javascript Decorators
One reason why Javascript rocks:
As a use case, imagine you want to restrict a certain set of functions to only run if you are logged in. Doing stuff like this is ridiculously easy with first-class functions.
Here’s a generic decoration example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
(function()
{
var original = function(paramOne, paramTwo) {
console.log('original: ' + paramOne + ' ' + paramTwo);
};
var decorator = function(originalFn) {
return function(paramOne, paramTwo) {
console.log('decorator: ' + paramOne + ' ' + paramTwo);
originalFn(paramOne, paramTwo);
};
};
var fnTable = {};
var registerCallback = function(url, callback) {
fnTable[url] = callback;
};
registerCallback('/abc', original);
registerCallback('/def', decorator(original));
fnTable['/abc']('one', 'two');
fnTable['/def']('three', 'four');
})();
|
Update: Here’s the specific way you’d do this with node.js/Express:
Since all of the URL handlers you register have the same signature, it’s easy to add precondition checks to the handlers via decorators.
1
2
3
4
5
6
7
8
9
10
11
12
|
var decorator = function(originalFn) {
return function(req, res) {
if (req.session.userLoggedIn) {
originalFn(req, res);
} else {
redirectSomewhere(res);
}
}
}
app.get('/url', decorator(original));
app.post('/other', decorator(original));
|
You get preconditions essentially for free, which is a damn sight better than adding the if() block to each and every handler function. Also, if you need more preconditions in the future, you can just stack them.
Starting Copies of Firefox with Different Profiles on Ubuntu
Repke Spaetzlerei: A Great Lunch Place
Stopped by one of my favorite spots for lunch today: Repke Spätzlerei, a cozy, cafeteria-style restaurant by Savignyplatz in Berlin.
It’s pretty busy at lunch time, as they have good deals for comfort foods like Spätzle, Schnitzel, meatloaf (Hacksteak), and Königsburger Klopse (€6,90!). The portions are a good size, but aren’t so large that they’ll put you to sleep at your next meeting. There’s always a good selection of freshly made salad sides such as: mixed bean salad, fennel and cabbage salad, or potato salad. Additionally, each of the lunch menu items usually comes with a mixed salad of some sort, with your choice of vinaigrette or yogurt dressing.
p.s. Don’t mind the crappy photos, that’s what I get for using a Motorola Milestone to take them.
Directions
Repke Spätzlerei
Bleibtreustrasse 46
10623 Berlin
Opening Hours
Daily from 11:30h