C# using statement, redux

Last week, I wrote about the things I had not known about the C# using statement:

Multiple objects can be used in with a using statement, but they must be declared inside the using statement, like this:

using (Font font3 = new Font("Arial", 10.0f), 
           font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

I’m beginning to wonder where it was I learned the using statement from, given that I really didn’t know this is supported. Granted, I learned my C# basics when the language was version 1.0, and while the older reference does have an example of this usage, it’s not as clear as the current version. Still, lacking this knowledge meant that I’ve (ab)used braceless blocks to achieve the same effect:

using (Font font3 = new Font("Arial", 10.0f))
using (Font font4 = new Font("Arial", 10.0f))
{
    // Use font3 and font4.
}

I wasn’t actually as far off as I thought – what the documentation doesn’t clearly spell out is that the syntax for the variable declaration inside the using statement must match a normal variable declaration. And there’s no way to do this:

string foo = “bar”, int baz = 42;

Because C# only allows you to initialize variables of one type in one declaration, and the same limitation applies to the using statement. The compiler knows this, the documentation wasn’t so clear about it. I’ve rarely declared two variables of the same type like in my example – instead, it’s been more like this:

using (DbConnection connection = OpenConnection())
using (IDataReader reader = connection.ExecuteReader(“…”))
{
    // ...
}

in which case the neater syntax doesn’t actually work at all. So I’m still stuck with my syntax abuse, unless I want to nest blocks. And this sort of seems to communicate my intent: I’m trying to say, the usages of these two things are linked in scope. Were I to do something to the connection before running the statement, I’d of course indent them differently.

I’m still waiting for a better idea.

Back in business

Back to work since yesterday, and hoo boy, it’s good to be alive. It didn’t take long for the hair pulling and swearing to begin, but in a good way. I enjoy the challenge of trying to clean up a messy code base – what I don’t enjoy are the days when progress is scarce.

Popped by the Uni for some Data Structures exercises and to catch a glimpse of my co-students. I felt like staying in, just because I really like the blend of people who appreciate quirky humor, geekiness, caffeine and code.

Today’s challenge was (and tomorrow’s still is…) creating a scheduled task that accesses some features that were – I hesitate to say “designed” – never thought to be useful outside a scenario where we know of a single logged user. It’s not feasible to try to extend the session concept to include a “working as the system here” type of session, due to a large number of potential, unexpected consequences. Hence the sane response seems to be to try and carefully write out the bits that always expect a session to be had.

Normal sleeping patterns are creeping in, after two nights of short, restless sleep and two consecutive mornings of still getting up between 6:15 and 6:45. Good thing I know this works, otherwise I might not have the willpower. I had almost three weeks to sleep as much as I wanted. That’s something I could get used to.

Don’t try this at home, we’re professionals

So I just received the feedback for my last exercises for the Data Structures course. Three mistakes total: I transformed an O(n) algorithm to an O(n2) one (although I spotted that one myself – after I had already submitted my answers, d’oh!) and my lazy-delete linked list was doubly borked: two successive deleted items confused my Purge routine altogether, and the search would stop on a deleted item.

Ouch.

OK, so I admit, I didn’t really pay attention to the search thing at all, and I’m taking some credit for figuring the O(n2) thing out myself, but damn, not checking for two successive deleted items in the key part of the algorithm I was actually working on. Sloppy!

Fortunately, at work I tend to interleave writing tests with implementing my algorithms, but I have to admit that I’m not sure if I would have thought to check for this case when doing TDD, either.

Sobering thoughts. One should never ever fall to the trap of thinking that a problem is so trivial it doesn’t merit a thorough checking. Because programming is hard:

  • If your code deals with arbitrary human text, it’s probably broken. (Have you taken the Turkey test recently?)
  • If your code deals with floating point numbers, it’s probably broken.
  • If your code deals with concurrency (whether that means database transactions, threading, whatever), it’s probably broken.
  • If your code deals with dates, times and time zones, it’s probably broken. (Time zones in particular are hideous.)
  • If your code has a user interface with anything other than a fixed size and a fixed set of labels (no i18n), it’s probably broken.

Let me add one to the list: if your code implements an algorithm you that you can’t verify for correctness at a glance, it’s probably broken. Especially if I wrote it.

Time for improvement

Today I had a long discussion – more of a one-sided rant, really – where I tried to convince two other programmers that quality stems from the programmer, and almost every programmer has it in their power to change things for the better.

Suppose you are given the task, of say, implementing a Frobnitzer for the next minor version of Blooperator. You open your editor and dive in to gain understanding on how to best implement the feature. Then you get that sinking feeling. The existing code was intended for a Flubbergleep instead. It was written by someone who left the company ages ago. It’s poorly documented. Worst of all, it looks like a mess. You sigh, and wish for the 307th time that the customer would agree to The Big Refactoring.

But nobody ever pays for refactoring only. And why should they?

Clean code is a nice thing to have, but from the customer’s standpoint, that’s not what provides the value. The customer just wants their Frobnitzer. While the existing code is ugly, with lots of tight coupling, obscure variable names and near-indecipherable methods, it works as expected.

You are a programmer. Your job is to solve problems for the business, even if they don’t acknowledge them.

Poor quality code is a problem. So solve it.

It doesn’t really require The Big Refactoring, even though it would be the easy way to do it. When you work out what that complex algorithm with lots of one-letter variable names is actually doing, clarify the variable names. When you’re forced to change a method that consists of 200 lines of arrowhead code, flatten it. If you can extract a method to clarify the meaning of the code, do it. There are automated tools that can do it and verify that they don’t make any semantic changes to your code. Use them — make any and every simplifying or clarifying change you judge safe enough to do while still shipping on schedule.

If you can, write tests for it. So you’ve got a 100kLOC project with zero tests, and seeing the first one throw a red bar is a bit disheartening. Grit your teeth, make it pass, then go for another one. In a week you’ll have a couple of dozen. In a month or so, you’ll probably surpass a hundred. And the next maintainer will thank you.

Most likely that maintainer will be you.

If it feels like you can’t write tests for it, I’ve got a book you need to read. Get used to the idea of working with legacy code. You’ll be doing that most of the time anyway.

Complaining endlessly about how you’re never explicitly given the time and resources to get things right is a cop-out. Making things better bit by bit is rarely easy, rarely rewarding and almost never appreciated by the customer. But it’s the right thing to do.

So quit complaining, and go do your job.

New things

Well, it’s been a while since I last took a chance and tried to change the way I use my computer. I’m fairly set in my ways, even though I realize that some of the ways I do things are fairly ineffective. I also feel I’ve sort of fallen behind the curve with regards to making good use of services on the web and whatnot, so I thought I’d try a couple of new things.

First, I’m trying Chrome as my default browser for… well, either until it annoys me and I go back to Firefox, or if it doesn’t, then possibly indefinitely. At first I disliked the idea of a browser without an ad blocker. And then I remembered Privoxy, which seems to pretty much cover what I used to have AdBlock for.

Second, after having read a lot of good things about Windows Live Writer, I’m going to use it to type these entries. In fact, I’m doing it right now, and my first impression is very positive. Apart from the installer that wanted first to install everything and the kitchen sink and then to sign me up for all sorts of things, this is the way software should work. Non-intrusive, helpful, not arrogant.

Third, I took ASP.NET MVC for a quick tour. I didn’t actually write an application yet, I just took a peek at the default app skeleton and futzed around a bit, because a guy on IRC said he found it hard to work with. Positive things: having gotten used to MonoRail in an earlier project, most things felt natural. I was quickly able to add an action to the default controller and modify its behavior. Less positive: the default configuration provides no obvious way of switching to another view engine (or, possibly, it did and I missed it), and I hate the default, which is WebForms. Still, I think it will be a fun framework to dabble with.

It’s funny, but I feel like I really need a project to play with now, while just yesterday completing the exercises for my Data Structures course felt like too much work. Speaking of which, I should take it upon myself to go through the list of essential things from the last couple of weeks and feed them to Anki. The spaced learning system seems interesting, and this would be a perfect time to try it.

Recovery-wise, the inflammation in the eye socket has clearly gone down, it feels more comfortable, and I feel like doing some physical exercise. In fact, I did a 30-minute workout on Wii Fit for the first time in almost six months. It felt good. I suppose I should take it easy for a couple of days still. But I’m definitely going to the sauna today. And have a couple of beers.

On that note, cheers. I’ll try to keep to a more intense posting schedule in the future.

We interrupt this transmission to bring you the latest news

LinAlg course exam is quickly approaching. I’ve already decided I’m going to go with LinAlg II and Discrete Math next period, and see if I can just exam my way out of English. I feel like I have a relatively good grip on matrices, a rudimentary idea of what vector spaces are and some tools to deal with them, but I’m still sorely lacking the exposure to math in general I’d need to be able to see solutions to the problems I’m being dealt. Still, I guess the fact that I’m not entirely lost is something I can be proud of.

Work is getting interesting. I’m getting a new cow-orker on my project, been doing some preparations to reduce the amount of confusion and ramp-up in advance by trying to ensure he’ll have a place to sit in and access to all the systems he’ll need to work with. Not doing as well as I’d like in the Flex department, but I manage.

What free time I have left is mostly spent watching Buffy the Vampire Slayer with the missus — she’s pretty much hooked now, and I’m glad we’ve got something we can do together that doesn’t take a whole lot of preparing. If it did, it might not get done at all.

I feel stuck in a weird place in my head where I don’t really know who to identify with. It’s easiest at work, since those are the people I spend most of my waking hours with, and luckily I’ve been seated with a bunch of people with whom I share, if nothing else, then at least a sense of humor. Ideologically speaking, it feels like we’re worlds apart.

At the university, it’s not as clear-cut. I have basically one person I talk to on a regular basis, and two semi-regular. Seeing pictures from the freshman events is a bit strange — I wish I could have been there, but I still think I wouldn’t quite fit in. It’s just not possible to jell with people with whom one spends so little time.

Then there’s all the other people I call friends. This schedule basically rules them out entirely, not that I’d see them very much anyway.

I know it’s just a question of reaching out to people and keeping the bonds working, but it feels like it would take more effort than I can put in.

On Thursday I have an appointment with an eye surgeon. Am going to talk to him about the evisceration. The thought still gives me the chills, but chronic pain really isn’t something I want either.

Flex: dynamically sized clipping container

Here’s something that took me two days to figure out: I wanted to have a VBox nested inside another VBox, which I shall call ChildOne and Parent, respectively. I wanted to add child components to ChildOne so that ChildOne would conjure up scroll bars on demand, which is what it does by default due to the clipContent property being true by default.

That was easy enough, apart from the fact that I also wanted ChildOne to fill up Parent except for a tiny bit at the bottom, say, 20 pixels tall, which would contain a button I shall imaginatively dub ChildTwo.

All the approaches I tried at first resulted in either ChildTwo getting squashed, ChildOne extending beyond what it was supposed to, Parent conjuring up the scrollbars or some combination thereof, until I figured out that I had to code around the issue.

The solution itself was simple: compute a fixed height for ChildOne from Parent.height - ChildTwo.height. But as it turns out, the heights weren’t available during the construction of Parent, nor in the FlexEvent.CREATION_COMPLETE event handler. Fortunately, perusing the Flex documentation, I noticed ResizeEvent.RESIZE which is rather conveniently also fired upon the first layout.

The full solution, then, was approximately the following:

public class Parent extends VBox {
  private var ChildOne:VBox = new VBox();
  private var ChildTwo:Button = new Button();
  public Parent() {
    this.addEventListener(ResizeEvent.RESIZE, this.resized);
  }
  private function resized():void {
    ChildOne.height = this.height - ChildTwo.height;
  }
}

This example is reduced to the bare minimum, so it doesn’t take to account things like paddings and margins and whatnot, but it may help someone. (Hi future me! Forgot this already?)

Note: I was originally under the impression that I should be able to do this with constraint-based layouts, but when I tried it, ChildOne no longer clipped its contents, opting to expand instead which then led to Parent clipping. This seems a bit strange to me, so mayhaps I was doing something wrong. If that happens to be the case, please let me know. 🙂

Quoted for truth

Found in a Reddit comment thread:

I moved to a bigger city in the hopes of joining a team of dedicated and talented developers. I’m finding myself at the top of this crew, which has kind of bummed me out. I’m not that good. I’m persistent, which gives me an edge, but I know I need to work with some people with experience to help take me to the next level.

1 2