Saturday, February 27, 2010

Russel's antinomy and stackoverflows

Russel's Antinomy goes like this (an extract from Gödel's proof):
Classes seem to be of two kinds: those which do not contain themselves as members, and those which do. A class will be called normal if, and only if, it does not contain itself as a member; otherwise it will be called non-normal. Let N by definition stand as the class of all normal classes. We ask whether N itself is a normal class. If N is normal it is a member of itself (because by definition it contains all the normal classes); but, in that case, N is non-normal because by definition a class that contains itself as a member is non-normal. On the other hand, if N is non-normal it is a member of itself (by definition of non-normal); but, in that case, N is normal, because by definition the members of N are normal classes. In short, N is normal if, and only if, N is non-normal. It follows that the statement "N is normal" is both true and false.

By reading this sort of stuff, we get reminded how all the stuff we work with as software engineers, comes from Mathematicians.

Anyway, this is what I came up with, inspired by the above:

public class NonNormal
   NonNormal _nonNormal = new NonNormal();
Now you just instantiate NonNormal and you'll get a pretty sweet stackoverflow.

I don't know about you, but this looks like a pretty elegant fuck-up to me.

Wednesday, February 24, 2010

Falling in line to the (micro)templating frenzy

A few weeks ago I would've laughed in your face if you told me I was gonna fall in line to the templating frenzy that seems to be spreading like a virus between coders. Now - one way or the other - I seem to be infected.

I recently tackled the challenge of generating a DTO layer (including mapping logic) from WCF service client using T4 (with no editor whatsoever - don't get me started). I honestly thought I was gonna blog about that sooner or later but then I immediately got shuffled around like a puppet to some front-end work (I am talking web here) and faced the lame-ass ordinary challenge of dynamically injecting repetitive structures into a given page in response to a given event (click-click-click-click ... click).

Coming from that T4 work, templating obviously came to mind as a way not to get bored: wouldn't it be great if there was something like T4 for js? It sounded crazy at first, but I started looking into it and immediately found the John Resig Micro-Templating engine.

There was no way I was gonna pass on that and, to be honest, the only alternatives were pretty lame:
  • implement your own templating engine 
  • shamelessly hard-code the markup to inject in your .js functions (as I always did before)
So I started playing with it and managed to stumble upon the Rick Strahl variation to it, which actually uses T4 syntax (it sure doesn't look like a coincidence) and also has a nice addition for error handling.

Anyway, this is getting too long: here's an example where I am adding divs with a bunch of input fields to a container, ids are generated at runtime depending on how many divs we have in there. It's ugly as fuck it gets, but it drags the message across (I think).

Let's start
you need to shove the templating engine function in a file. I called it templating.js and you can just copy paste whatever Rick Strahl has on his article. Once you've done that, add templating.js and jQuery.js as external script files to your html.

Once you have that in place, it's time to populate you jQuery init function and add your micro-template (the micro-template is added in a script element defined as text). This should be pretty straightforward if you read the comments:
<!-- all this goes into the head section --> <script type="text/javascript"> $(document).ready(function() { //IDs for the first div var idsArray = { divId: "div_0", input1Id: "input1_0", input2Id: "input2_0" }; // logic to add the first div function onLoad() { var templ = $("#myRepeaterTemplate").html(); var parsed = parseTemplate(templ, idsArray); $("#myTarget").html(parsed); } // inject the first div onLoad(); // Add onclick handler to button w/id addBtn $("#addBtn").click(function() { //1. count how many divs var size = $("#myTarget > div").size(); //2. generate name value pairs var myArray = { divId: "div_" + size, input1Id: "input1_" + size, input2Id: "input2_" + size }; //3. invoke parseTemplate var templ = $("#myRepeaterTemplate").html(); var parsed = parseTemplate(templ, myArray); //4. append $("#myTarget").append(parsed); }); }); </script> <script id="myRepeaterTemplate" type="text/html"> <div id="<#= divId #>" > <input id="<#= input1Id #>" type="text" value="some input" /> <input id="<#= input2Id #>" type="text" value="some input" /> </div> </script>

And the following is what you need in the body of the page for this to work:

<div id="myTarget">
   <p>this stuff should be wiped on load</p>
<input id="addBtn" type="button" value="Add" />

This is just a very basic example that should be suitable when you just want to inject some markup given a template, but you can put actual js logic into the template. For a nice example of that have a look at this nice example here.

I am a lazy-ass late adopter, and if I am using this stuff  (talking about the templating frenzy in general) - it generally means it can't be ignored much longer. Do so at your own risk.

Wednesday, February 3, 2010

GetProperties(BindingFlags.DeclaredOnly) returns no properties

If you're trying to use reflection to retrieve a list of properties and you want only the properties declared in a given type but not the inherited ones, msdn says you need to call GetProperty passing down the DeclaredOnly binding flag.

What msdn doesn't say is that if you just pass down DeclaredOnly you'll get nothing back (and if you ended up on this post through a google search that's probably the reason why).

In order to get back the properties you're looking for you need to pass down also the Public and Instance binding flags - smt like this should work:
var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
This is probably working "as designed" but could definitely make you waste a bit of time (as it did for me).

In the spirit of human hive intelligence - hope it helps some other average Joe out there.