May 05

OCDinner: Iespējams, dīvainākā pseido-“ballīšu spēle”

Pirms nu jau krietna laika izdomāju iepirkšanās spēli, kurai nav ne jēgas, ne tāda saturīga mērķa, bet nez kāpēc tomēr laiku pa laikam sagribās uzspēlēt. Vakar draugu pasākumā tieši bija viena šāda reize, tāpēc nolēmu pie viena arī pierakstīt noteikumus uz virtuālā papīra.

Spēles princips ļoti vienkāršs — mēģināt nokomplektēt ballītes / vakara ēdienu galdu, pērkot tikai tās ēdamās lietas, kas veikalā neatrodas savā vietā (nosaukums nāk no no maldīgā priekšstata par OCD kā vēlmi, lai viss būtu savās vietās, tīrs un kārtīgs). Piemēram, kola, kas nolikta uz saldējumu vitrīnes, cepumu paciņa, kas mētājas šokolādes tāfelīšu grozā, “Snickers”, kas iebāzts starp “Laimas” šokolādēm utt.

Papildus apsvērumi:

  • Ieteicams samērogot izvēlētā veikala izmēru ar spēles dalībnieku skaitu. Vienam cilvēkam tīrīt milzu hipermārketa hektāru nebūs īpaši produktīvāk, kā 10 cilvēkiem Narvesen kiosku.
  • Preces, kas atbilst noteikumiem, ir jāņem obligāti! Pārtikas preces, kas neatbilst nosacījumiem, ņemt nedrīkst!
  • Jāņem tikai ēdamlietas — lietas, ko kāds no dalībniekiem ir gatavs vismaz pagaršot. Pārtikas preces, par kurām ir zināms, ka tās tiks izmestas pat nepagaršojot, neskaitās ēdamlietas un nav jāņem.
  • Spēle dabiski beidzas tad, kad veikals ir izstaigāts un visi nevietā esošie produkti savākti. Minimālais daudzums, pie kura spēli var pārtraukt, ir viens pilns iepirkumu grozs vai arī sasniegts spēlei atvēlēto finanšu limits.
  • Prece, kura acīmredzami ir vienkārši nejauši izkritusi no plaukta (uz grīdas vai apakšējā plaukta) tehniski neskaitās (spēles būtība ir savākt lietas, ko kāds cits ir apzināti paņēmis un nolicis nevietā), bet tas ir tāds “ne šis ne tas” variants un spēlētājs var izvēlēties — ņemt vai nē.
  • Alkohola kā ēdiena statuss ir diskutabls (un tas arī ir relatīvi dārgāks), tāpēc tā iekļaušana pirkumu sarakstā ir pēc katra spēlētāja ieskatiem / kopīgas vienošanās.

Spēles noteikumu angliskā versija no Halceona jūsu un mūsu starptautiskajiem draugiem.

Feb 20

JavaScript gotcha: inherited properties do not get created until assignment

Everyone know JavaScript has some weird gotchas, such as the already infamous JavaScript equality table. While a good framework / compiled language (such as LiveScript) will let you easily avoid a lot of them, there are things inherent to the way JS works that you can’t really sidestep. One example: properties defined on the prototype.

Let’s say we have a simple constructor function:

var ctor = function() {
  ctor.prototype.number = 15;

  ctor.prototype.increaseNumber = function() {
    this.number += 5;
  }
}

Now, here’s what would happen

var obj1 = new ctor();
var obj2 = new ctor();
obj1.number // 15
obj1.increaseNumber();
obj1.number // 20

obj2.number // 15

Everything as it should be. However, if the property was an object, and instead of setting its value you accessed it’s properties, something weird would happen:

ctor = function() {
  ctor.prototype.testObj = {};
  
  ctor.prototype.changeTestObj = function() {
    this.testObj.testValue = 50;
  }
}

obj1 = new ctor();
obj2 = new ctor();
obj1.changeTestObj();
obj1.testObj.testValue; // 50

obj2.testObj.testValue; // 50 - WTF!?

Those better at thinking in JavaScript probably aren’t surprised, but I sure was. Why would the value be modified on the instance in one case, but on the prototype on the other? The answer is, because JavaScript only creates instance copies on assignment. And since ctor.testObj is never actually assigned to from the object instance — only its property is accessed — JavaScript doesn’t create a new instance property and instead modifies the one in the prototype. Which means it modifies every “new ctor()” instance everywhere in the code.

The solution? Set the instance value in addition to prototype value in the constructor, if you must use prototype at all.

ctor = function() {
  // Do NOT use x = y = 12 assignment syntax, you'll just end up with the same
  // problem because of both instance and prototype properties pointing to the
  // same object
  this.testObj = {}; 
  ctor.prototype.testObj = {};
  
  ...
}

Apr 28

Why are you wishing cancer on me?

While the described problem is objectively real, this is, overall, an emotional rant. Adjust expectations & interpretation accordingly.

It started with Microsoft .NET’s MVC model binding (if you don’t know what model binding is, here is a short and simple explanation). Localization in a business application is not a luxury, or an extra, it is a fundamental, non-negotiable requirement. Do you know how to localize the error message that .NET’s DefaultModelBinder throws if you enter “Owl” in a text field that’s bound to an int? No, you don’t, and good luck finding out. If you dig deep enough in the source code for DefaultModelBinder, you will find the magic string that you need to put in your resources to make it work. Oh, you also wanted to localize the error message for when the value is missing (null) for a non-null variable? Dive right back in and look for the other magic string.

Mind, these are not some 1% edge cases, missing and wrong values are one of the most common errors in web data input. And if you want the error messages to say anything other than the default English text, you need to hunt through the source code for a hard-coded magic string that you then have to put in your resource (eliminating any custom localization mechanisms that don’t rely on the resource provider pattern). That’s not even insane, that’s just evil.

“Oh, I know”, you say, “I’ll just extend & override …” No. You will not. Because the part that generates the error message is buried so deep inside non-virtual and private methods that if you try, you will end up either giving up and wrangling with the resources, or giving up and re-writing the whole ModelBinder (or using mine, once I finish it and put it up on GitHub & NuGet) just so that you would have something that can actually be extended where it matters. And, quite possibly, murdering some kittens, in which you would be totally justified at that point.

Then came HtmlTags from the FubuMVC project. It’s a beautiful, elegant little library for generating HTML tags and passing them around as objects, thus allowing further modification by other parts of the code before output. This is opposite of the .NET’s MvcHtmlString, which is just that — a string (that’s protected from double-encoding).

And I was happily using it for a while, until I stumbled upon a seemingly trivial need that turned out to be an insurmountable challenge. What was this decadent, arrogant and completely unreasonable demand that I had the gall to expect from this humble little piece of code? I wanted *two* tags. Specifically, I wanted to take a HtmlTag and make a copy of it. And again, my evening was filled with one “can’t” after another. I can’t Clone() it because it’s not ICloneable. I can’t use a constructor that takes another HtmlTag and creates a copy of it, because there is no such constructor. I can’t use AutoMapper, because the tag’s attributes are of type HtmlTag.HtmlAttribute, which is a private class. And I can’t extend and override it because everything that isn’t already public, is private.

Why? Why do good programmers hate other programmers so much? I understand that making convenient extensibility points isn’t trivial, but what’s wrong with “protected”?

You know what? I’m just going to shortcut all this and declare — “private” is evil. “sealed” is evil. Unless you have a nuclear-bunker-rock-solid reason, every time I see “private” in someone’s code I will read it as “I hope whoever uses this gets cancer and dies”. Because that’s how it feels. Declaring private members in your code feels like you’re wishing cancer on me.

Please, “public/protected virtual” everything by default.

Thank you.

Apr 28

What is .NET MVC model binding

Model binding is the part of the framework that takes an input from a HTML form (or other formats) and converts it into an object in code. So that if you have this HTML form:

<form method="post" action="/BindModel">
  <input type="text" name="UserText" />
  <input type="text" name="UserNumber" />
  <input type="submit" value="Send" />
</form>

When you click the Send button, it will send whatever has been put into the input fields to the server, at the URL “/BindModel”. On the server side, in code, you have a simple class:

public class UserData {
  public String UserText { get; set; }
  public int UserNumber { get; set; }
}

Model binding lets you define an action like this:

[HttpPost]
public ActionResult BindModel(UserData input) {
  // code here
}

When the BindModel method is executed in response to clicking the Send button, model binding takes the contents of the form and copies the values over to the object (function argument) “input”. There will even be an error if the user entered something that isn’t a number in the second field, because the UserData class specifies that UserNumber is of “int” data type.

There is, of course, much more to it, but this is the core.