Best Practices

What’s wrong with this code? A bit of background for this example; `driver` is a Selenium::WebDriver object, the Selenium server is remote. Also, this technique is applicable to all expensive code that does the same thing over and over.

def first_name_field
  (driver.find_elements :id, "name")[0]

unless first_name_field.nil?
  if first_name_field.displayed?
    if first_name_field.enabled?
    first_name_field.send_keys "Dylan"

Apart from being terribly contrived, this code is bad because every single interaction with first_name_field causes a call to find_elements, which in turn reaches out to the Selenium server. You’re adding a network round trip every single time, and for no reason. Instead of asking the browser to do this:

  1. Find the “name” element (line 5)
  2. Check if the name element is displayed (line 6)
  3. Check if the name element is enabled (line 7)
  4. Send the string “Dylan” to the name element (line 8)

You’re asking it to do this:

  1. Find the “name” element (line 5)
  2. Find the “name” element (line 6)
  3. Check if the name element is displayed (line 6)
  4. Find the “name” element (line 7)
  5. Check if the name element is enabled (line 7)
  6. Find the “name” element (line 8)
  7. Send the string “Dylan” to the name element (line 8)

That’s nearly twice as many commands, effectively doubling the length of your test, for no gain at all. You only need to find an element once and you can interact with it until Selenium’s reference to that object is invalidated. This only happens when the page you’re on mutates to another (either directly via URL commands, through clicks on buttons that navigate, or by Javascript).

This doesn’t just occur through Selenium commands (although Page Object Model code and libraries are often prone working this way). Loading configurations, accessing web services, validating data. There’s many places where you’ll burn up cycles (and correspondingly incinerate coal and warm the planet dooming us all just a liiiiitle sooner. Yeah, I actually do think wasted compute matters.) and, maybe more sellable to your Product Owner (who clearly doesn’t care about the environment), this will make your code faster.

Are you writing this down, and taking a memo?

No, like, literally. Take a memo. This kind of memo. Memoization is where you save the result of an expensive operation and return the saved result every time the operation is requested. Like responding to everything your Mum says on the phone with “Uhuh”, Memoization swaps one resource (computing time or brain-cells) for another (memory or engagement). Memory is cheap. You can probably throw more into your server if you need it.  (But you don’t need it. Just… You don’t, trust me.)

If you use Ruby, you’re probably already taking advantage of Memoization:

def proscuitto_pizza
  @proscuitto_pizza ||=

That’s right, the ||= operator in Ruby effectively does Memoization; If the variable exists, it does nothing, else it sets it to the code on on the right of the operator. Wrap the whole lot up in a method name and you’ve got a memoized value.

For example, we could re-write the code above as so:
def first_name_field
  @first_name_field ||= (driver.find_elements :id, "name")[0]

That single line change means that Ruby will remember the field in question and we won’t need to ask the Selenium server for it again, saving us a heap of time.

(Selenium Sidenote – Unless the page changes of course. How do you know if the page changes? Well, every navigation will do it (including those involving submitting forms) and some AJAX requests do it. You need to understand how your site is implemented… But then, you should anyway so you know what you’re actually testing).

(Some more reading on the ||= operator)


Git (and its ilk) are tools for working collaboratively (especially with hosted services). Your commit messages are your best weapon for communicating context, and every collaborator, including Future You, depends on context to be productive. It’s not opinion, it’s Science!

See, human memory is so bad it can be erased by passing through a doorway. We can defeat doorway-induced time wasting (not to mention the change of screaming “what the hell is this?!” at code someone, maybe Past You, wrote) with great commit messages.

Randall from knows what's up.
(Image courtesy of XKCD because Randall is a champ.)

A great commit message:

  • Is never ‘left behind’ by code changes (unlike comments)
  • Gives all the info you need (ticket numbers, reasons for change, expected behaviour changes)
  • Shows relevant changes around your change
  • Summarises everything in 50 characters or less as the ‘subject line’

All this info, the context of the change, makes problem solving (read: coding) more efficient.  Good context helps any collaborator; there’s evidence that context-based approaches to problem solving are more effective.

Continue Reading


I generally don’t make New Years Resolutions.  The entire process is so arbitrary and self-loathing, it plays into the whole annus horibilis bollucks.  If you’re going to improve your life, just do so; Don’t wait for some arbitrary point to go this is the year I will be self fulfilled, all my dreams will approach realization, I will open my code chakras and purge my stale git stashes and finally learn how the hell to use Vim.  If you’re constantly trying to learn new things you’re going to be better off then it you wait to be pushed by the last two digits of the date++.

At least pick more then one point in the year to fix ALL The Things.  One thing a month.  You’ll get continuous benefits for your life and won’t be exhausted from trying to change everything all at once.  You don’t want to go through all the stress of making a change, just to suffer from a fit of Extinction Bursts all at once.  Failing at multiple goals at once can lead to feeling like a children’s toy that’s been run over, by a leaking sewerage truck, in the rain: Useless, disgusting and prone to making gross squelching sounds.

However.  It’s excellent blog credit to give a list of your New Years resolutions; Gotta get those views, that’s how you get that Internet Monies from the Internet People (Or so I hear).  So instead of giving my resolutions, I’m going to make some suggestions that everyone else could adopt.  Please feel free to give me all the credit for these, despite the willpower being expended by you and you alone.  There’s going to be twelve in total, one for each month.  Here are the first three, and I’ll publish the rest every quarter, just to kill off the temptation to start them all at once.

Improvement One: Learn a Tech

Learning a new technology has an obvious benefit: It makes you more employable.  Personally I think this is the least beneficial aspect.  Learning a new tech, especially one that is wildly different from what you do day-to-day, makes you better at your current job.

It’s been solid advice for a while, that learning a different programming paradigm makes your code better in all languages.  I don’t actually buy this.  “writes Java in Ruby” is the same as “acts Functionally in JS“; they’re both paradigm contamination.  I think that practise makes you better, but that’s a very different thing.

No, the reason that I think learning a tech makes you better at your job is it lets you talk to other developers in their language, shows you the strengths of technologies that might make your own specialty more useful, and allows you to better boot-strap individual projects.  A shinier prototype is more likely to be turned into a Real Project.

I personally really like Code School for learning new tech.  I gave up on books because it’s difficult to know what’s worth reading and what isn’t, until you’ve enough experience to evaluate the content and, well… that experience is what you’re reading to build.  I like Code School because it treats the viewer like an adult (unlike at least one competitor) and because it builds in logical, sensible ways.  I’m not getting paid for this recommendation (although if Code School wants… call me!), I just like the product.

Improvement Two: Take a Step to Better Financial Management

Capitalism is pretty gross.  It’s also widely entrenched in society and unlikely to be replaced by anything better before the AI post-scarcity uprising, and I hear that project didn’t meet its KickStarter goal.  Money is here to stay, and Money roughly correlates with ability.  Not ability to accomplish tasks; ability to get others to help (or at least get out of the way).

Spare funds give you the ability to quit and find a better job.  Spare funds allow you to buy tools for your hobby and improve your mental health.  Spare funds let you travel.  Spare funds let you start a side project, that gets profitable, that makes you more spare funds.  It’s kind of crap that having money makes it easier to make money.  It makes life less stressful.  It literally makes you less sad and maybe happier up to a point (The literature is mixed.  This is a nice summary. TL;DR Money gives you options.  Wow, what a familiar argument…).

This is not financial advice.  I do not know what your goals are… But maybe you’re lucky enough that with focus and willpower, you can put yourself in a place with more ability to achieve them.  Maybe start with an Emergency Fund?

Improvement Three: Be a Part of your Tech Community (more)

This one is pretty easy: Get more involved in a tech community.  The cold hard reason is that it’ll serve as good networking.  Screw that.  Tech is (or should be) fun.  Tech people are some of my favourite kinds of people.  There are meetups for languages and tools and industries all over the world.  Go to a conference (like!) and deliberately talk to people you don’t know. Head to your local meetup.  Join and post to some Open Source Mailing lists.

If you’re already involved, step it up.  Pitch talks to conferences and meetups.  Organize an event.  Go to a longer event or workshop (Rails Camps are amazing).  Mentoring is a huge benefit to our industry, so find a junior dev and offer.  Help less-connected people get integrated by going with them to events and introducing them to others.

Especially try to find unique and interesting voices and share them with others.  We can be faddy, prone to hero worship and appealing to authority.  Mix it up!  Share things you don’t often here, from people who aren’t often heard.  Everyone gets better that way.

Postscript: Sorry to Preach

I really really can’t stand New Years Resolutions, which is why this post is deliberately delayed.  All of these are suggestions of things that I’d like to accomplish myself, and may be helpful in your life.  They’re not aimed at anyone in particular, nor do I warrant their practicality or easy.  Any feedback, leave a comment below!


Something that will, sadly, not be a secret to many of you: Some people are awful.

Even if you think it’s acceptable to be a rude arrogant jerk to people in private, (and would you want, as queer person, to work with someone you know donates heavily to prevent marriage equality, even ‘in private’?) it’s very hard to argue that it’s OK in professional life.  Open Source is no longer just a fun hobby; it’s a professional reality that you will use and (hopefully) contribute to Open Source.  Unfortunately there are people in many many projects, often in significant roles, that will say things that are cruel, hurtful, that erase and trivialise people’s identities and personal triumphs and disadvantages.  They’re being bullies ‘at work’.  That’s super NOT OK.

One of the best ways to make communities professional and welcoming to beginners, as well as enhancing diversity, is to adopt and enforce a Code of Conduct.  Ashe Dryden answers all of the questions you might have about why and how far better then I could, but I want to re-enforce five things:

  1. Having a (good) Code of Conduct makes your project more welcoming to everyone willing to not be a prat.  Diversity is at the heart of the Internet
  2. Code of Conduct violations are not about being offended, they are about being unprofessional
  3. You may have a right to freedom of speech but there’s no right to freedom of consequences
  4. If there’s ‘no problem’, then there’s no harm in adopting a Code of Conduct!  (Spoiler: there totally is a problem)

And number five:

  objection.text = "but you're discriminating against my right to discriminate!"
rescue RediculousCircularObjectionException => e
  objection.objector.judge :pretty_harshly
  objection.objector.rebutt "Really? Really. You think that's a coherent argument?"

You know who’s not awful? Coraline Ada Ehmke.  She’s actually really great.  She’s proposed a Code of Conduct for Ruby Core (and wrote the original Contributor Covenant) and you can find that proposal here.  All y’all with Core Ruby accounts should go support it.

What do we have to lose?  Awful people, that’s what.  HUZZAH!


Internet Comments, am I right?

They’re occasionally a useful source of discussion (usually in curated communities or niche content) but mostly, they’re a swirling cesspoll.  The comments are where people write hateful, toxic vitriol.

On YouTube this is often in the form of attacks on the presenter.  Open Source projects, though, tend to get more… religious.  Your product isn’t their favourite product and thus must be purged.  They want a feature from the thing you made and gave them for free and DAMN HOWDY if you aren’t the worst person alive for not giving it to them.  They don’t understand how to use it and so you must perish.

If you leave pointlessly negative comments on Open Source projects, screaming demands or trashing the free work people have done for you, then as far as I’m concerned you suck as a developer and you’re a bad person.  I have more respect for the noobiest of noobs then I do for people who piss all over others in Open Source.

I’d never hire anyone who made their team-mates feel bad when they wouldn’t do something optional for them.  I’d never hire someone who yells at others rather then fixing bugs, who acts like they’re entitled to things, who can’t interact professionally in public situations.  As far as I’m concerned, you’re not a good developer if you do those things, you’re a terrible staff member who happens to be OK with development.

Being a good Open Source citizen in the venues you use it is, in my mind, a defining characteristic of good devs.  “GitHub Resumes” aren’t useful just because they show your work style but because they show your workplace style.  How you’ll get along with others.  Whether I can trust you to not ruin my team.  If you’re helpful and good at communicating and compromising and not a complete dickhead.

(Corollary: If you defend people who do this because they’re productive or talented or useful for the project, you’re also a sucky developer and a bad person.  We don’t let famous surgeons ignore ethics no matter how brilliant.)


So I worked all weekend this week. I won’t get paid. I won’t even get a nod from my boss, although I was there for even longer for a standard work day. Jerks. Time to burn the office down. Get my stapler back.

OK, so they’re not jerks, and I wasn’t working at work. I was at Brisbane’s Global Day of Code Retreat, taking generous advantage of the Thoughtworks office’s fridge and wifi.

The idea is that you spend a day focusing on implementing the same thing over and over, so you can hone your professional skills. In the same way as a sculptor might practice straight lines over and over, we implemented Conway’s Game of Life using TDD techniques in 45 minutes. Every 45 minutes you had to delete your code and tests, debrief, and start again with a new constraint. Some of the constraints felt more annoying then educational, but on the whole I felt I got something out of every session. I also got to teach a couple of people something about TDD & RSpec, and I love helping others improve, so I got a kick out of being able to contribute like that.

I’m going to post how I found each session today, then mull over the others and post some observations a little bit later. I think it’s best to see how learning effects you in other contexts (like actually at work) before you jump into critiquing it, so I’m going to see how the next work week goes.

Session 1

Language: Ruby
Testing Framework: RSpec

This session just booted people off into implementing Conway’s life. I worked with a young Thoughtworker whose name eluded me, and we got about halfway into an implementation before time was up.

We spent the majority of this session just discussing what way to do things. I was a big fan of using a “Cell” object which maintained a list of its own neighbours, without directional information because it doesn’t matter. Doing it like this allows for arbitrary topologies (And I suspected that might be one of the constraints.)

Potentially tricky issues with this approach include implementing the tick for every cell at once(If you duplicate the cells, you have to duplicate the network and ensure you’ve duplicated every cell with its new state. If you mutate the network in place, each cell needs to know if it’s neighbours have ticked, and if so, what their state was last tick.

At the end of the session we had a discussion about what techniques people tried. Having a “Cell” object was quite popular (OO is like herpes, it spreads with contact), there was one “have a universe holding an array of cells” solution, and the one which I liked most, which was using the co-ordinates of the cells as a key for a hash of booleans, representing whether the cell is alive or dead. I really liked this… It’s unbounded (unlike an array in many languages) and *doesn’t* require a hojillion objects.

Session 2 – Ping Pong

Language: Ruby
Testing Framework: RSpec
Constraint: Each time you write a test, you ensure it tests properly, then you pass it to your pair and they have to do all the implementation. Then they write the next test, and you implement that

This session we decided to try the hash technique one of the groups suggested last time. I say”we decided” but actually mean “I decided”, because prevarication frustrates me, my partner had no strong opinions and I thought it sounded interesting so I made a snap decision.

The Ping Pong criteria is how I’d probably prefer to do pairing in the future, although usually it irks me (I need to be doing something and my “I’m not doing anything” behaviors usually irritate my pair). It meant that your tests had to be higher quality, and there was a defined place where you had to hand over to the other member of your pair — No long stints at the keyboard or just watching.

We didn’t get an implementation finished though, although I worked out how I’d like to derive neighbours. I proceeded to teach people a tiny bit of matrix math all day (more on that later)

Session 3 – Silent Ping Pong

Language: Ruby
Testing Framework: RSpec
Constraint: The same Ping Pong TDD as before, but this time you’re not allowed to talk

I paired again with a Thoughtworker this time, a gent from China called Hiyun (I hope, sorry if I’m wrong mate >.>). Wow. Dude was a shortcut pro. I learned a shittonne of RubyMine shortcuts and tricks I’d always wanted too but never devoted time to (Which is obviously my fault). It was really cool, probably my favorite session of the day.

We went back to the “Cell as self aware object” paradigm (drink). With the exception of a couple of inadequate tests, this session worked remarkably well. The inadequate tests required a lot of gesticulating. Once you’ve written something it’s hard to prove that the test is wrong rather then the code.

I think not being able to talk focused our attentions on communicating *only* our requirements through tests. There was no discussions of where you worked, what you thought of Test::Unit VS RSpec, why’s DHH’s hair like that; it was purely a “get shit done” event.

I think the most surprising thing was that we finished. It was almost like being unable to design architecture by consensus made one arise naturally out of requirements, which I am… skeptical of. I’m not sure how well our solution would have accommodated change, but maybe most software projects are simple enough that it doesn’t matter.

Session Four – No Primatives

Language: Ruby
Testing Framework: RSpec
Constraint: Rather then using native types to store results, cells and so on, use a wrapper class or object. No Arrays of cells, no returns true

Oh god so hard. Getting away from primitives in Ruby is hard. Every time I wanted to wrap something I heard a tiny voice in my head stop talking about bees, games, cooking and Alice in Wonderland for a minute to scream “NEEdleSS ComPleXItY!“. All I wanted to do was use built in objects so I could rely on methods that Someone Else Has Tested™.

This session, we did something horrific. We decided that, if we weren’t going to use primitives, we’d use something as far removed as possible. Something so non-primative it’d make your eyes haemorrhage.

Yup. Files. To check if there was a cell at (4,5), you checked the directory ./data/4 for file 5.cell. If it existed, it was alive. Touch a location to make a cell alive, rm to delete it. We were planning to store the current generation number in the file to allow for ticking.

How’s that for non-primitives, bitches?

Session Five – Tests must pass in 3 minutes

Language: Java
Testing Framework: JUnit
Constraint: Once you start writing a test, you must write code to make it fail in three minutes or less. If you get to three minutes without it passing, you must revert all you changes and delete your test

The intent of this constraint, I believe, was to force you to test small amounts of functionality rather then huge sweeping changes. The idea is that small tests are good tests, and it’s tempting to write large tests that try to do too much. When they fail, you’re not actually sure why, and you lose much of the advantage of a full test suite.

My pair (Hi, Mike!) and I chose Java because it was our lingua franca (Scala was preferred but it’s quite hard to use a language without a dev environment, oddly enough). This may not have been the wisest choice, because of one simple truism:

Fuck me Java is Verbose!

It’s not just the punchline to the “what’s wrong with other people’s languages” joke. It was never really bought home to me just how verbose Java was until I had to spend so much time setting up each test. I’d just spent most of the day writing Ruby and now I’m having to give all my tests annotations and a typed, static method signature, and set up my variables types, and then set up and type the method and ensure to return the right sort of thing, and just making so much boilerplate it nearly made my eyes bleed (I propose we call this Stigjava.)

Even Mike, who writes Java for a living, was surprised. He said it bought Java’s verbosity into stark relief after a day of writing Ruby and Haskell. It forced us into doing true TDD because otherwise we simply couldn’t make a test that tested anythingin time. We had to implement the minimal amount every single test pass. Here’s how we had to test that we could get a list of neighbours for a cell:

  • Write a test to ensure that there is a “getNeighbours” method. Just that one exists. Pass it
  • Write a test to ensure the method returns an (empty) ArrayList. Pass it.
  • Write a test to ensure the method returns an ArrayList containing eight things
  • Run out of time because it took so long to learn how much code we could write at once

It was just astonishing. I’m not Java bashing (so passé), just really surprised. Writing the code to pass things, and even the tests, wash’t too hard, just getting to a point where we could do something took forever. And Mike is an IntelliJ wizard – Otherwise we’d have been screwed. He was making sweet combo love to the keyboard to bust out methods and variables and implement the signatures correctly and we were still fighting the clock.

Session Six – No Returns

Language: Ruby
Testing Framework: RSpec
Constraint: None of our methods could return values.

Woah. OK. Globalling it up. During this session I had a bit of an idea how to use events to generate a grid of neighbors, but didn’t implement it cleanly. Actually, this session was embarrassing because I forgot that Ruby is pass-by-reference, so resorted to using Globals. Don’t tell my mother. The solution wasn’t really productive, just because every time I manipulated the global objects I felt dirty and wanted to cry.

During this session, the pair using Haskell gave up on the constraint and just started trying to get it working at all. Globals were popular (at least we weren’t alone wallowing in filth) and only one group used callbacks. The idea I’d had was callback/eventing based, but wasn’t async, so obviously I need to do a bit more work about doing that kind of programming at need, rather then when forced.

Then, we had beer, a debrief and a powwow. Roughly half the room left straight away and the rest wanted to hang for a bit, which I always enjoy. I’m looking forward to the next one. I’m thinking this time, we use the presence of machines on a network as live cells….


Edit: Aaaaaaand it’s fixed.

You may have noticed, sometime in the last few days, that the fantastic Ruby IDE RubyMine from those lovable Scamps JetBrains, has been having a small problem. Nothing too shameful or embarassing but well, it wants to keep it to its doctor and partner.

Oh Well, this is the internet. Medical Disclosure AHOY!

Instead of getting useful output, RubyMine is suffering an exception discharge from its testhole. It looks much like this:

Running tests...
ArgumentError: wrong number of arguments (0 for 1)
              run_suite at C:/Program Files (x86)/JetBrains/RubyMine 4.0.3/rb/testing/patch/testunit/test/unit/ui/testrunnermediator.rb:41
         start_mediator at C:/Program Files (x86)/JetBrains/RubyMine 4.0.3/rb/testing/patch/testunit/test/unit/ui/teamcity/testrunner.rb:131
                  start at C:/Program Files (x86)/JetBrains/RubyMine 4.0.3/rb/testing/patch/testunit/test/unit/ui/teamcity/testrunner.rb:119
                    run at C:/jruby/jruby-
                    run at C:/jruby/jruby-
  change_work_directory at C:/jruby/jruby-
                    run at C:/jruby/jruby-
                    run at C:/jruby/jruby-
                 (root) at C:/jruby/jruby-

Process finished with exit code 1
Empty test suite.

Well OK. That’s… That’s not good. You might want to get that seen too, RubyMine. Let’s run some scans and take a swab of those lines.


alias :old_run_suite :run_suite
  def run_suite
    count = calc_patched_size(@suite)

    # Notify test reporter attached

    # Notify patched size
    notify_listeners(TC_TESTCOUNT, count)    
    # delegate call to super

Well something’s being aliased to old_run_suite, and it’s in Test::Unit::UI::TestRunnerMediator. Let’s check that out:

       def run_suite(result)
 do |channel, value|
            notify_listeners(channel, value)

Huh. That’s a non-optional argument alright. Wait how could that have ever worked? As far as I can tell this should always have resulted in chunks being blown all over my development environment, like when you go to far towards a Ballmer Peak.

A little bit of culturing, some firm poking and prodding and analysis of older versions helped me discover Issue 28 on Github. What happened is:

  1. run_suite had been changed to run in test-unit-2.4.9, which broke RubyMine
  2. One of the JetBrains developers, Vlad, asks for a fix. His reasoning is that a maintenance version change is meant to be totally backwards compatible
  3. Kou implements an alias for test-unit-2.5.0
  4. Vlad asks why the minor version has changed, and asks about the versioning protocol which test-unit is using. He suggests the delightful Semantic Versioning because it’s awesome, and Bundler and (critically) Rubygems use it. So anyone saying they want gem "test-unit", "~>2.4.0" will never get the fix
  5. Kou replies that they don’t use semantic versioning, and that Monkey Patching makes your code harder to maintain (well duh) and that, if you’re relying on it, you should specify versions (rather then have the package maintainer have to maintain monkeypatchability, much like how you’ve got that dick friend who chucks a tanty if you don’t keep their favorite brand of cracker in the house because they’re “ALLERGIC!!!!1!” to the others so suddenly it’s your problem not theirs. Ahem)
  6. Kou then decides to remove the fix completely because he doesn’t want to maintain backwards compatibility, he wants to build new shit. He also offers a way to make their code work, that places the burden on them, not him

Good points from both sides really, because my opinion is coloured with the idea that monkeypatching is an atrocious idea. If you can possibly get away without doing it, don’t do it. If you do, then you’re responsible for ensuring it continues to work, not the packages you’ve patched. If this means you have to tell your customers to use a specific version, well, that’s your concern.

As for semantic versioning, I think it’s a great idea and to be a good citizen, you really should be using it. I’m big on standards and when a large majority uses the standard and you don’t, I think it behooves you to maybe consider if you can, especially for something like release versioning.

Anyway, the fix for all this is rather simple, just edit your gemfile to say

"test-unit", "=2.5.0"

and wait for an updated version of RubyMine, with which you can use later versions of test-unit.


What is wrong with this guy’s tutorial?  No thoughts?  OK.

How about this guy?  (Who is possibly even more egregious.)

I’ll give you a hint.  Even ScottGu is doing it.  In fact, he’s kinda responsible.


*{Sigh}* It feels better to have that out there.

Code belongs in Controllers.  Constraint Code belongs in Models.  Views?  They’re meant to be templates, and just templates.  Code should be limited to conditionals and loops, but only where those loops might change their display formatting.

Helpers are where you’re supposed to put formatting functions and template manipulation code.  Helpers are also usually not just littered all over your damn templates because Hey, they’re View Related right?.  Wrong. Also, I hate you.  Sure, it’s up to the individual developers to follow MVC principles, but most people are sheep.  You’re just encouraging them to write shitty applications.

There are some cures.  If you put your helpers in your App_Code folder, they’re fairly self-contained (although the syntax is still disgusting).  You can declare them as extensions to HtmlHelper (Same link as before).  And, using Single File Generators you can turn them into reusable libraries (Thanks David Ebbo!)  Just please, please, don’t put this crap directly into your views.


I consider Cheat Sheets a staple of development.  I refer to this regex cheat sheet once every few days.  They’re great to jog the memory, especially since most of the time, you’ll need two or three pieces of information from them.  Developers don’t need to remember syntax, they need to solve problems.  Cheat Sheets help.

So, with all that in mind, I’m compiling a cheat sheet called “Stupid Little Cheats”, full of the things I see in code that shit me, because there’s an easier, better way.  If you do these little things in your code, I will mock you, because you are writing crappy code.  They’re small, but that also means they’re easy to avoid, so it’s easy to enhance your codebase.  And yes, I’m totally guilty of them from time to time.  My blog, my right to name-call and be a hypocrite.  You Nazi.


This shits me:

var valueToReturn = null;

if (a.Thing() == some.Stuff){
   valueToReturn = DoAnotherThing();
} else {
   valueToReturn = DoAThirdThing();

You have no idea HOW MUCH that shits me.  You’ve spend 5 lines, 4 braces, 1 semicolon and a ton of my patience, irrationally.  There is an operator called the ‘Conditional‘ operator.  Shock and Awe, it is used to conditionally run some code.  “Just like that if statement!” you cry.  No.  It’s not a waste of my time like that if statement is.  It works like this:

valueToReturn = (a.Thing() == some.Stuff) ?  DoAnotherThing : DoAThirdThing

If the condition is true use the thing on the left, otherwise use the thing on the right.  Simple.  Elegant.  Easier to write, read and understand. Stop using single-line variable assignment if statements.

Null Coalescence

OK, so now that you’ve shown the junior dev on your team the above (You know, the one you’re mentoring, because YOU totally know about the Conditional operator, right?), you can stretch yourself a bit, because there’s something wrong with THIS code:

var returnThing;
if (aThing != null) {
  returnThing = aThing
} else {
  returnThing = defaultThing

return returnThing

So what’s wrong with THAT code?  Is it:

A: You should be using the Conditional Operator, ala

 returnThing = (aThing == null) ? aThing : defaultThing

B:  You should returning in-block, ala

return (aThing == null) ? aThing : defaultThing

C:  Your code is crappy, verbose and you should be ashamed

D:  You’re still being in-efficient

Correct, the answer is ALL OF THE ABOVE.  The reason?  You’re not using the Null Coalescing Operator, ??.  It’s wonderful.

In C#, taking any type that is nullable, it can return the item OR a default, in a single line.  The above code can be re-written like so:

returnValue = aThing ?? defaultThing;

But we can go further, and eliminate the returnValue altogether.  This has the advantage of saving us a variable creation, assignment and type referral, and stopping the whinging of those who can’t stand when you exit a method or function halfway through a control structure.  (This last advantage is the greatest of all).  Here’s the example:

return aThing ?? defaultThing;

Six lines shorter.  No braces, variables or winging.  Except from people who complain that “Some people won’t understand that statement!  It’s less maintainable!”.  Fuck ’em.  You’re a craftsman.  You have a responsibility to learn how to use the tools available to you, especially when they’re simple… And you have some cheat sheets.

Update: Screwup and Pro Tip!

So, I screwed up the code in my examples and got a wee bit confused when writing them *{sigh}*, thanks to Nick Wilson for pointing that out.  He also shared a neat tip with me:

Since the assignment operator returns a value, you can use it to initialize properties when using accessor methods:

public List<Something> ListOfSomethings
    get {
        return _listOfSomethings ?? _listOfSomethings = new List<Something>();

Thanks Nick!