The Endless Obsession

better code

Octopress Post Excerpts and ‘Couldn’t Parse YAML’

This evening I noticed a syntax error in my blog’s ATOM feed. The error seemed to stem from the text in one of my more recent posts, what exactly I didn’t bother to determine. However, I also noticed that the post summaries were rather large and didn’t appear to do a good job of summarizing post content in any case. So, it seemed the best thing to do was to figure out how I could get Octopress to use a better summary and kill 2 birds with one stone.

I discovered that the YAML that lives in each post’s header (more on that later) could include an “excerpt” property where I could write my own summary of the post.

For example, here’s the header of this post:

---
layout: post
title: "Octopress post excerpts and 'couldn't parse YAML'"
date: 2013-10-15 21:14
excerpt: This evening I noticed a syntax error in my blog's ATOM feed. The error seemed to stem from the text in one of my more recent posts, what exactly I didn't bother to determine. However, I also noticed that the post summaries were rather large and didn't appear to do a good job of summarizing post content in any case. So, it seemed the best thing to do was to figure out how I could get Octopress to use a better summary and kill 2 birds with one stone.
comments: true
categories: 
---

This worked so well that I promptly went through all of my posts and threw up some quick excerpts without much thought. Unfortunately I soon ran into an error: ‘parse’: couldn’t parse YAML.

I hadn’t thought about it until now, but the configuration at the head of each post is YAML. I don’t know much about YAML, but apparently something was wrong with one of my excerpts.

Fortunately I was able to track it down to the “:” character, which is somehow significant in YAML syntax. YAML Lint was an invaluable resource.

File.OpenWrite Gotcha

Recently I ran into an odd problem when writing a text file to disk using .NET’s File.OpenWrite.

using (var fileWriter = new StreamWriter(File.OpenWrite(outputFilePath)))
{
    fileWriter.WriteLine("abc");
}

You might expect that after executing this code the text in the file would be “abc”. Not quite. In my case I was sometimes seeing results like this…

abc
some other text

…where “some other text” is the last bit of text in the file before writing.

It turns out that the documentation for File.OpenWrite contains the answer.

If you overwrite a longer string (such as “This is a test of the OpenWrite method”) with a shorter string (such as “Second run”), the file will contain a mix of the strings (“Second runtest of the OpenWrite method”).

OpenWrite behaves much like the dreaded insert mode in word processors and text editors.

The solution that I chose is pretty simple. Just clear the file’s contents beforehand.

Chrome Select Excessive Padding

Recently I noticed that dropdowns (<select>) in chrome suddenly had an excessive amount of padding on my Windows 7 PC. This is what it looked like.

Screenshot of excessive padding

I did some digging on the web and found a chromium bug report.

One of the comments near the end of the page gives the solution to the problem.

Actually that is the problem. Windows has a service called “Tablet PC Input Service”. When this is running Windows 7 thinks it’s a tablet instead of a desktop. Once I turned this off and restarted chrome the drop down spacing is correct. But as soon as I turn the service back on the extra spacing comes back.

Sure enough, there was a service running on my laptop called “Tablet PC Input Service”.

Screenshot of excessive padding

…and when I stopped the service and restarted chrome, the padding went back to normal.

Screenshot of excessive padding

My laptop is a touchscreen and turning off this service doesn’t seem to affect touchscreen functionality. Don’t forget to change the service startup type to “Manual” or “Disabled” so that it doesn’t start back up the next time you log on.

This Google Groups post might also be relevant.

Should You Write Awesome Code?

I ran across this provacative post on the tubes: How I stopped writing awesome code. The following is my reaction and thoughts (hastily thrown together). Go to the link and read it first or what follows probably won’t make much sense.

I certainly agree that some of the practices he mention can have little benefit in the short term. Many people pointed out in the comments that the short term gains of “trimming the fat” can come back to haunt you on long term projects, and I’ll second that.

Someone in the comments described how they have frequently inherited projects where it looked like the developer(s) had this mindset and it usually turned out to be a mess/headache to maintain. I think the mental burden he described to understand concepts/tools like IOC, ORMs, etc. is only one side of the coin. The other side is that not following best practices and using powerful tools that are available can be just as frustrating to a developer who inherits the project (or even your future self), especially in the event that the app has to be significantly enhanced or changed. That said, I have also had the experience where I found that I had over-engineered a project too early and ended up “stuck” with some of those poor decisions later on. I think the key is to not try to over-engineer too early, but rather follow only tried and true best practices that require little added effort and could yield future gains, improve and refactor as the project grows, and never be satisfied with where things are today. For what it’s worth, in the case where I made regrettable engineering decisions early on, I was also deviating from common/best practices, i.e. trying to be clever.

As for F12, I don’t think you can ever really get around the limitations of the IDE with respect to interfaces and abstract/virtual members. I have been in the habit lately of using Shift+F12 (symbol search) rather than “Go to Definition” unless I know for sure that there is a single implementation of the member that I’m trying to get at. Resharper is also a good choice to improve the IDE experience. As irritating as F12 can be, I wouldn’t use that as reason to avoid using useful language features.

Finally, to tie it together with an anecdote: I can think of two projects off the top of my head that seem to fall into the too extremes. One was hastily thrown together by a freelance developer to meet a client need. The source control wasn’t hosted on a popular OSS hosting services, it was just offered up for download on the blog. There were no unit tests. Most of the code was in a single class file with a number of supporting classes that were essentially just data containers. On the one hand, I ended up having to significantly enhance that project and found it to be very frustrating and painful. On the other hand, if he hadn’t thrown it together it may be that nothing like it would have existed at all and I would have been forced to start from square 1 (and making my own mistakes as a result). The other project was a highly engineered and conformed to a highly detailed open specification, complete with interfaces, IOC, and unit tests galore. On the one hand, when I discovered a bug I was able to easily verify the bug via unit test, fix it, and see it go green. On the other hand, the project is not very active now (has been somewhat superseded by other technology) so you could argue that the effort was wasted.

Its all about balance…

Also, someone pointed out that its possible to write tests as UI acceptance tests that actually interact with the web browser (using Selenium) and mimic user behavior. I happen to use WatiN instead in my day-to-day, but what’s important is that you can verify the behavior that your clients are going to be looking for in an automated fashion. Do it!

Thanks to Jonas for provoking critical thought! :)

Carolina Code Camp 2012 Presentation

Recently I co-presented with Bobby Dimmick at the annual Carolina Code Camp, put on by the Enterprise Developers Guild of Charlotte. The event was wildly successful, with sold-out attendance and a day fully booked with speakers.

Pictures from the event

Our presentation was entitled “Building rich, model-centric, event-driven web apps using EF, Razor & open source”. The approach we took was to build a demo application from the ground up, and document the process so that it was reproducible. The app is hosted at todoapp.exosuite.com and the walkthrough is at todoapp.exosuite.com/walkthrough.

Screenshot

You can build the app yourself by following the walkthrough. I promise, I did it many times! :)

Learning F# With TDD: Part 2

Last time I talked about setting up F# testing using NUnit, TestDriven.Net, and NaturalSpec.  This time around I’ll elaborate a little bit on the testing aspects, and also talk about active patterns.

ExoWeb Type Loading Changes

I recently posted a message to the ExoSuite Google Group in regards to type loading in ExoWeb.

Batch loading

Types are now batch loaded. This means that prior to type caching your pages should only send a single type request (or very few depending on your usage). This was implemented to cut down on the large number of requests sent from the browser, since browsers have limits on the number of concurrent request.

You don’t have to do anything to enable this functionality.

Type loading and rules

We noticed that a surprisingly large number of types were being requested, and some of them didn’t seem like types that should be needed. I was able to track this down to the “AllowedValues” rule, which was force loading types when instantiated. Since this rule is very common, and often spans types, this would result in a cascading type loading effect. I changed the rule’s active type loading behavior to a passive approach: it becomes enabled when the relevant types are loaded.

There are two possible side-effects of this change that come to mind.

First, if you happen to have an allowed values property on a type that is neither the containing type of the property or the property type, then the rule may never be enabled, even if the data is all loaded and editable. This is an odd scenario that shouldn’t happen in practice. To illustrate, if type Person has a property Org of type Organization, and its allowed values are World.AllOrganizations, and type World is not used, then the rule will never be activated. The only way that this example makes sense is if the type World is a required type for the entire app (or feature area), and so will always be available.

Second, if you are not actually referencing a type in your query paths but subsequently used that type in templates/scripts or expected a $extend to fire when the type was loaded, then in the past you may gotten away with this because of the overly aggressive nature of type loading. Now, types are only loaded because they are referenced in your queries or are otherwise required for object loading (i.e. due to lazy loading). One caveat: several other rules (e.g. CompareRule) may still force type loading to occur. They are less likely to actually change the nature of type loading, but still this behavior may also be changed in the future for other rules.

The moral of the story: don’t depend on rules to perform type loading.

Learning F# With TDD: Part 1

I decided to dive into a few languages I’ve been meaning to learn by way of the calculator kata.  First up: F#.

First, some prerequisites.

  • F#, obviously.  This comes with VS 2010 so you probably already have it.

  • We’re doing TDD, so we need some sort of testing framework.  I decided to go with NaturalSpec.  This means we’ll need to download the package from github, build it, and also download and install NUnit and TestDriven.NET.  The author has a good blog post on setting up and running the test project.

Keep in mind that I’m extremely new to the language, so the code I ended up with probably doesn’t reflect what a seasoned F# programmer would write.  I tried to follow conventions that I could pick out as much as possible.  The first part of the kata is an add function.  Pretty simple.  In the interest of not getting bogged down in one language I didn’t take if very far, so I will only be able to make very broad observations at this point.

Two positive things that I took away from it:  pattern matching and pipe.

Pattern matching is something that I knew was popular in functional programming circle but had never experienced first hand.  Now that I have a taste of it I think it’s a handy abstraction, but I have a feeling that I haven’t even begun to scratch the surface of what it could mean.

let addNumbers (numbers : List) =
    match numbers.Length with
    | 0 -> 0
    | 1 -> numbers.[0]
    | _ -> numbers |> Seq.reduce (fun a b -> a + b)

This is simply an alternative form of the familiar if-else branching logic, nothing special really, but it is pleasantly terse.

Pipe is even more exciting.  Take the following for example.

numbers.Split ',' |> Array.toList |> List.map int |> addNumbers

Using the pipe operator (that’s “|>”) you can stream a value through a series of transformations, in this case splitting the string, converting the array to a list, converting the items in the list to integers, and finally passing the list to a method called “addNumbers”.

In any other language this would probably read similarly if your transformations are all instance methods, however, that breaks down as soon as you have to use global or static/class methods.  The pipe form always reads nicely from the beginning to the end.  Of course, this example could be a little simpler since our function can technically accept an array as its argument.

To be continued…

Disable the Audible Beep in Mac Terminal

This was starting to get on my nerves.  I really don’t need a fancy sound clip to keep reminding me that I deleted as far as I can go.  I always do that, since I’m a bit OCD.  This one took me too long to find, mainly becuase of tabs.

Anyway, to disable the sounds, go to Terminal -> Preferences -> Settings (top tab group) -> Advanced (inner tab group), look for the “Bell” group label and uncheck the “Audible Bell” option.  Note that this is specific to a particular settings configuration/theme, so if you switch themes the behavior will change.

Tfs Rollback

Using the tf command line tool you can rollback all or part of a tfs checkin.  This is useful for two reasons: 1) If you at least want to roll back all changes in one or more file (not some changes in a file) then it saves you from having to manually revert changes (I’m a firm believer in not giving yourself the opportunity to goof up) , and 2) the checkin is actually marked as a rollback, so you don’t have to rely on checkin notes to identify it as such.

As a side note, based on what I’ve seen in the way that tfs represents changes, this rollback changeset is simply an add, edit or delete, with the additional information that it was a rollback of a prior change.  The original checkin is still in the tfs history.

To do a rollback, first open up the visual studio command prompt.  You should have a shortcut in your start menu.  On my machine the command is: %comspec% /k “”c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat”” x86.

Here’s the help for tf rollback (using the command tf rollback /?):

TF - Team Foundation Version Control Tool, Version 10.0.30319.1

Copyright (c) Microsoft Corporation.  All rights reserved.

Rolls back the changes in a single or a range of changesets:

tf rollback /changeset:changesetfrom~changesetto [itemspec] [/recursive]

            [/lock:none|checkin|checkout] [/version:versionspec]

            [/keepmergehistory] [/noprompt] [/login:username,[password]]

tf rollback /toversion:versionspec itemspec [/recursive]

            [/lock:none|checkin|checkout] [/version:versionspec]

            [/keepmergehistory] [/noprompt] [/login:username,[password]]

Versionspec:

    Date/Time         D”any .Net Framework-supported format”

                      or any of the date formats of the local machine

    Changeset number  Cnnnnnn

    Label             Llabelname

    Latest version    T

    Workspace         Wworkspacename;workspaceowner

First, we need to make sure we are working within our workspace.

cd path\to\workspace\root

So, for example, we could rollback an entire changeset:

tf rollback /changeset:12345

Or, we can rollback a single item in the changeset:

tf rollback /changeset:12345 $/Path/To/Item

There is also a login param that you can pass if needed:

tf rollback /changeset:12345 /login:domain\username,password

Enjoy!