Modeling inheritance in Mongoose

For my latest hobby project, I am using NodeJS. Working with JavaScript on the server side is super fun, but it has it drawbacks as well. As you might know, JavaScript is not an object oriented language but a functional language and it uses prototypical inheritance instead of class based inheritance. This does not imply, however, that you cannot emulate classes and class based inheritance. Here’s the proof:

function A() {}
A.prototype.doStuff = function() {
    console.log('doing stuff...');
};
function B() {}
B.prototype = new A();
B.prototype.constructor = B;

var a = new A();
var b = new B();

console.log(a instanceof A); // true;
console.log(a instanceof B); // false;
console.log(b instanceof A); // true;
console.log(b instanceof B); // true;

a.doStuff(); // doing stuff...
b.doStuff(); // doing stuff...

If you want to override the behavior of an instance method, just attach the override to the subclass (B.prototype). You can always call super() by invoking it directly, like so:

B.prototype.doStuff = function() {
    A.prototype.doStuff.call(this); 
    // Or: A.prototype.doStuff.apply(this, arguments); which also passes the arguments
};

The call (of apply()) invocation will execute the method A.prototype.doStuff with respect to a certain context (In this case, this).

This is all real fun, but it is useless in Mongoose. Once you start working with Models, the inheritance relationships are lost because of the way Mongoose treats schemas. Luckily, I’ve come up with an elegant solution and it does not involve the mongoose-schema-extend hack.

The project I am working on is an event-based game. The behavior of each event is encapsulated within an Event “subclass”. This scheme corresponds to the Command Design Pattern. For the purpose of replays, all the events are stored in a single collection because a collection-per-eventType approach is clearly not recommendable here. In order to distinguish different event types, there is a discriminator field inside of each event document. Within my execute method, I could just use a switch(this.type) statement but this would result in a terrible shotgun surgery. Instead, I ended up doing this:

var mongoose = require('mongoose'),
    map = {
        DROP: require('./eventHandlers/Drop'),
        PICKUP: require('./eventHandlers/Pickup')
        // ... more event handlers here
    };

var event = new mongoose.Schema({
    date: {
        type: Date,
        default: Date.now
    },
    type: {
        type: String,
        enum: Object.keys(map)
    },
    params: {}
});

event.path('type').validate(function (value) {
    return '' === value;
}, 'No EventType set');

event.methods.execute = function (game) {
    return map[this.type].execute.call(this, game);
};

module.exports = exports = mongoose.model('Event', event);

This way, all event type specific handling behavior is encapsulated inside a single file that looks like this:

module.exports = exports = {
    execute: function (game) {
        // Event handling goes here...
    }
};

This also allows to add other event specific overrides here (I’t thinking of validation because the params property can contain any data, other hooks, etc.). No more shotgun surgery, just register the handler with a discriminator keyword. Working inheritance and no more headaches, all thanks to Object.prototype.call().

Repack Eclipse for Mac OS X

On Mac OS X, applications are packaged in a “special” way. All application code is contained in a folder with a name ending in .app. Finder will run the program inside such folders instead of showing its contents. This is an elegant model: the application is contained in a single folder, which can be dragged around and you don’t need to know which binary you have to execute in order to run the program.

But then there is Eclipse, which completely ruins this philosophy. Eclipse is shipped as a regular folder, with a .app folder inside it. The binary inside the .app folder loads the application code from folders outside the .app folder.

eclipse/
    artifacts.xml
    configuration/
    dropins/
    eclipse
    Eclipse.app/
    epl-v10.html
    features/
    notice.html
    p2/
    plugins/
    readme/

The application is no longer contained, relies on external sources and it looks awful in your /Applications folder. Fortunately, you can very easily repack Eclipse to look just like a regular OS X application. First, lose the eclipse (all lowercase) symlink. You don’t need that anymore. Now move everything from the eclipse folder (except Eclipse.app) to Eclipse.app/Contents/MacOS. Last, you need to modify eclipse.ini, located in Eclipse.app/Contents/MacOS. This file tells Eclipse where the application code resides. When you open this file and look at its contents, you will probably realize very quickly what you need to do. Change the paths for the startup and launcher.library flags so that they read (beware that the versions of your plugins may differ!):

-startup
./plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
--launcher.library
./plugins/org.eclipse.equinox.launcher.cocoa.macosx.x86_64_1.1.200.v20120522-1813

That’s all! You now have a properly packaged Eclipse app for OS X. Everything should work like it used to.

I really don’t know why Eclipse is shipped in this retarded way for OS X. There was a entry for this in their bug tracker once but is now marked resolved, even though it is not.

While you’re at it, you can also change some of these flags. For instance, if you’re developing Android apps, you can speed up ADT by changing the following flags (According to StackOverflow).

-Dosgi.requiredJavaVersion = 1.6
-Xms128m
-Xmx1024m

USB On-The-Go (OTG) on the HTC Flyer Android tablet

About two months ago, I bought myself an android tablet. It had to be a cheap tablet but I did not want to sacrifice battery life or build quality. I ended up buying an HTC Flyer for about 250 euro.

While exploring the product, I discovered USB OTG information in the Settings application (see picture). Intrigued as I was, I opened a tab and searched the Internet for more information. Is it really supported? Does HTC offer the necessary accessories? I could not find the answers to my questions and this explains why I am writing about this.

USB Storage on HTC Flyer

I wanted to get to the bottom of this, so I started a quest to figure this out. At that time I did not have a USB Host OTG cable. For a while, I thought of soldering a converter using regular USB connectors, but the 4th, or ID pin in a USB micro-B connector (which is needed for OTG) is not used in regular USB data cables (Male USB-A/male USB micro-B). The large male A connector has got only four contacts. I searched the web and found two converters for about $2 (including shipping!). I ordered them right away. What is two dollars?!

When they arrived, I tried it. It did not work. No lights, nothing. Kind of disappointed, I put them away. A while later, I stumbled upon a forum post mentioning that the USB port in the Flyer does not produce enough current to power the USB device. I could not believe that I did not think of that.

Using a pen drive, a USB Y-cable (it has two USB-A male connectors and one female) that shipped with some external portable hard drive and a USB charger (probably any adapter with a female USB A connector will do), I tried it again. Great success! The light on the pen drive started blinking and on the tablet a message appeared: “Preparing tablet storage…”. In the settings app, the information of the pen drive became available.

USB Storage on an HTC Flyer

I used Inka File Manager on my tablet to browse the contents of the pen drive. The contents are located in /sdcard/usb (see picture). Even though the setup is rather clumsy, it works like a charm.

USB Storage on an HTC Flyer

But I don’t want to use the OTG functionality to read pen drives. I want to use it to transfer my photos to my tablet during holidays. I bought a Sharkoon Media Reader S (it’s small, light, cheap and it works with most flash storage) and hooked that up in the same way as I did with the pen drive. Again, great success!

Conclusion

It works, but it requires a rather clumsy setup using the following materials:

  • The HTC Flyer, duh
  • a USB OTG converter
  • A USB Y-cable
  • A USB charger
  • Your preferred USB device: for instance a pen drive or a USB card reader

Note: If it does not work right away, don’t panic. Try it again after rebooting your device or try changing the connections. Also, check that the device you are using is formatted properly. The Flyer can only read FAT32 formatted devices. NTFS formatted hard drives don’t work. I tried, without success…

Disclaimer: Normally, none of the above instructions will damage your device. If however, for some reason, your device gets damaged I cannot be held responsible for it. Use these instructions at your own risk!

USB On-The-Go (OTG)

USB On-The-Go, often abbreviated USB OTG, is a specification that allows USB devices such as digital audio players or mobile phones to act as a host allowing a USB flash drive, mouse, or keyboard to be attached and also connecting USB peripherals directly for communication purposes among them. (source: Wikipedia)

Vanillerisotto

Na een geslaagde maaltijd, komt een geslaagd dessert. Na een korte speurtocht in de keuken bleek dat ik probleemloos de vanillerisotto kon maken. Dat heb ik dan ook maar gedaan.

Het is de eerste keer dat ik een risotto en/of rijstpap maak en het is me zeer goed bevallen. Dit was eenvoudig en leuk. Bovendien is het nog eens superlekker ook. Je moet alleen een beetje opletten met de hoeveelheden. Ik heb het gerecht klaargemaakt voor twee personen maar ik had ruimschoots voldoende voor vier potjes. Ik heb ook maar twee eieren gebruikt in plaats van drie. De rijstpap is al zwaar genoeg. À la riche hoefde voor mij dus niet echt.

Het resultaat mag er wel wezen. Na er eentje opgegeten te hebben, kan ik meedelen dat het meer dan goedgekeurd is! Het is heerlijk! Dit ga ik zeker nog maken.

Vanillerisotto

Vanillerisotto

 

Kip met appelmoes en kroketjes

Omdat kroketten toch niet voldoende zijn als volledige maaltijd, heb ik ook nog kip met zelfgemaakte appelmoes gemaakt. Hier gaan mijn kroketten wel goed bij.

Omdat ik maar eten voor mezelf moest maken, heb ik wat geïmproviseerd voor de bereiding. In plaats van een hele kip te maken, heb ik een kippelbil gekocht in de delhaize en deze in een potje klaargemaakt. Ik heb een kleine ui in grote stukken versneden, samen met een teentje look en tijm en laurier. Dit heb ik dan in “een klontje boter” gestoofd en daar mijn kippenbout  aan beide zijden in gebruind op een sterk vuur. Daarna heb ik het vuur zacht gezet en het deksel op de pot gezet zodat het kipje nog lekker verder kon garen. Resultaat: lekker, sappig gekruid kipje.

Voor de appelmoes heb ik gewoon het recept gevolgd. Fluitje van een cent. De appelmoes was eerst wat te vochtig maar dat is snel opgelost door het vocht te laten verdampen. Minder water is de boodschap.

Toch een geslaagde maaltijd als je ‘t mij vraagt het heeft me verdomd goed gesmaakt!

Kip met appelmoes en kroketten

Kip met appelmoes en kroketten

Kroketten maken

Het land stond in rep en roer toen Jeroen Meus in het programma ‘Dagelijkse Kost‘ toonde hoe je kroketten kan maken. Iedereen holde als een gek naar de winkel om een millecroquettes te gaan halen. Ik ben echter al jaren met dit handige toestelletje bekend. Sterker nog, dit was mijn favoriete speelgoed als kleuter. Ik kon me er eindeloos mee amuseren. Voor mij is kroketten maken dus een zekere vorm van nostalgie.

Sinds die bewuste aflevering wou ik het ook wel eens proberen. Ik ben dus naar de supermarkt geweest en heb me wat loskokende aardappelen gekocht en met veel enthousiasme begonnen aan de kroketten, wel 63 stuks!

Kroketten

Een leger van kroketjes

Het ging allemaal uitstekend tot ik ze in de friteuze legde. Eerst ging het goed. Een beetje schudden met het mandje zodat ze niet aan elkaar gaan kleven. Even later begon het vet echter sterk te bruisen en te knetteren: water! Mijn kroketten waren duidelijk niet droog genoeg. Eentje is ontploft, met de nodige spatten tot gevolg. Gelukkig stond ik op enige afstand. Twee andere kroketten zijn (quasi) leeggelopen. Dju! Alvast geen dendererend succes.

Wat de smaak betreft, zijn ze alleszins wél een denderend succes. Daar kan een diepvrieskroket niet tegenop!

Ik moet wel onthouden voor de volgende keer dat de aardappelen nog niet droog genoeg zijn op het moment dat ik denk dat ze droog zijn. De puree moet door en door droog zijn.

 

Brood bakken

Ik ben de laatste tijd redelijk actief in de keuken. Ik kook namelijk graag en nu ik eens tijd heb, maak ik gebruik van die tijd om wat dingen te proberen.

Een daarvan is het bakken van een brood op authentieke wijze. Al enige dagen ben ik naar demonstratiefilmpjes op het internet aan het kijken. De bereidingswijzen lopen erg uiteen: van amateuristische bereidingen (zout rechtstreeks op de gist etc.) tot demonstraties in een professionele keuken (bakkers etc.). Als goede beginneling mik ik uiteraard ergens daartussen en ik begin met een wit brood. Dat is naar het schijnt het gemakkelijkste.

Omdat alle recepten verschillen, volg ik gewoon het recept op de bloemzak. Ik weeg alles en zet het klaar. Tijd om te beginnen! Bergje maken met een kuiltje, boter en zout aan de buitenkant, gist oplossen in lauw water. Veel te weinig water, lijkt me maar ik stel me daar verder geen vragen bij.

Wat later zit ik met mijn handen in het water en de bloem tot ik me bedenk dat ik met slechts 30ml water bezig ben in plaats van 30cl (300ml) wat op de verpakking stond. Shit! Ik probeer mijn handen wat proper te maken om nog 270ml lauw water van de kraan te nemen maar het wordt een knoeiboel. Memo to myself: zorg dat alles JUIST klaarstaat.

Uiteindelijk komt alles wel min of meer goed en ben ik als een gek aan het kneden. Klaar  om het deeg voor een eerste keer te laten rijzen. Dus ik leg het in een kom, bedek het met een doek en zet dit in een oven die rustig op 40 graden staat te draaien. Mijn deeg rijst voornamelijk in de breedte maar het rijst dus ik ben tevreden.

Na 30 minuten haal ik het terug uit. Het volume is netjes verdubbeld maar… het plakt helemaal aan de kom. Dju zeg! Ik pruts het voorzichtig los maar ik kan het niet goed te baas blijven. Ik moet het dus wel weer even wat kneden.

ik geef het brood wat vorm en leg het in de ovenschaal. Doek erover en laten rusten voor een 40-tal minuten. Het brood rijst weer voornamelijk in de breedte. Jammer… Ondertussen verwarm ik de oven al op 250 graden. Op die manier hou je nog voldoende hitte over wanneer je de oven opent om het brood erin te zetten. Het brood zelf bak ik op 200 graden.

Tot mijn grote vreugde groeit het brood tijdens het bakken toch nog een beetje in de hoogte. Hoera! Na een halfuurtje kan ik het uit de oven halen. Ik had gehoopt dat het iets beter zou loskomen maar dat was niet bepaald het geval. Misschien moet ik in het vervolg de ovenschaal toch maar een klein beetje invetten of een vel bakpapier gebruiken.

Wat de smaak betreft, staat het ook nog niet helemaal op punt maar voor een eerste keer is het zeker geslaagd. Ik vind dat het nog wat te veel naar gist smaakt en dat het redelijk zwaar is. Dat tweede is waarschijnlijk te wijten aan mijn redelijk brute behandeling na de eerste rijs. Het eerste is misschien op te lossen met wat meer bloem of minder gist. Ik vind zelf ook dat het brood nog een beetje te vochtig is. Een beetje extra bloem lijkt me dus zeker geen slecht idee. Ik denk trouwens dat dit het deeg ook ten goede komt: een droger deeg is stijver en zal dus minder in de breedte rijzen. Verbeter me als ik fout ben.

Al bij al toch een geslaagde poging. Het brood is lekker vanaf de tweede snede, wanneer je de gistsmaak niet echt meer proeft. Charlotte en ik hebben het toch met veel smaak opgegeten voor onze trip naar Amsterdam.

Tot slot nog een beeldje van mijn broodje.

Brood