Tuesday, August 30, 2011

backups-mode for emacs

github: backups-mode for emacs

John Siracusa's excellent Ars Technica review of Mac OS X Lion includes a page on Apple's new document model API. The intent of this API is to effectively end the practice of manually saving a document. Instead, applications will auto-save your documents in the manner of Google Docs or iOS applications. There are many scenarios where this will be helpful. John describes a few.

  • The student who writes for an hour without saving and loses everything when the application crashes.
  • The businessman who accidentally saves over the "good" version of a document, then takes it upon himself to independently reinvent version control—poorly—by compulsively saving each new revision of every document under slightly different names.
  • The Mac power user who reflexively selects the "Don't Save" button for one document after another when quitting an application with many open windows, only to accidentally lose the one document that actually had important changes.
  • The father who swears he saved the important document, but can't, for the life of him, remember where it is or what he called it.

Apple will now enable the following experience as written by John.

  • The user does not have to remember to save documents. All work is automatically saved.
  • Closing a document or quitting an application does not require the user to make decisions about unsaved changes.
  • The user does not have to remember to save document changes before causing the document's file to be read by another application (e.g., attaching an open document with unsaved changes to an e-mail).
  • Quitting an application, logging out, or restarting the computer does not mean that all open documents and windows have to be manually re-opened next time.

I will add that file versioning is another aspect of Apple's API.

  • The user can explicitly choose to save a version of the document.
  • Old versions can be found and viewed.
  • Old versions can be reverted to. This saves the current file as a version and switches the chosen backup with the current file.

With backups-mode I've set out to approximate Apple's Document Model idiom in emacs. Here's how I accomplish it.

  • emacs already has an auto-save feature that is turned on by default. Therefore, if emacs crashes, a user can revert from this file that is saved periodically.
  • I've redefined kill-buffer and save-buffers-kill-emacs to automatically save any file-based buffer when closing a file or quiting emacs.
  • I've turned on emacs' version-control and am saving old versions of a file to a central location instead of said file's location.
  • The user can save a version of the file they are editing with the save-version command bound to \C-cv.
  • The user can list all versions with the list-backups command bound to \C-cb.
  • After listing old versions via list-backups, the user is taken to a special backups-mode buffer where they can:
    • View an old version in read-only mode
    • Diff two versions
    • Revert from an old version
backups-mode buffer

Installation, configuration, and usage documentation can be found on github.

Monday, August 29, 2011

Smelly code, smelly code. Why are they writing you?

There are certain times in your career as a developer when you come across code so horrible, it causes you to question your faith in humanity. Such was the case when my boss and I were given the MicroMain Web Request application to install on one of our servers. We couldn't get it work even though we followed the instructions meticulously. We even spoke to one of their support people. Unfortunately, he was not one of their headset hotties. The error message we were getting wasn't too helpful, either:

Format of the initialization string does not conform to specification starting at index 0

This is a generic .net message. The issue was that we couldn't connect to the database. However, our SQL Server hadn't recorded a login attempt from the application. We were thinking it was a configuration issue. The web.config file was valid xml. Nothing looked terribly strange. Thankfully, they also provided us with the source code. Probably an accident. Nevertheless, we went to the function that was causing the error and were horrified by what we saw.

Public Shared Function GetConnectionString() As String
   'Dim sOleDb As String
   'Dim cn As OleDbConnection
   'Dim cmd As OleDbCommand
   'Dim dr As OleDbDataReader
   Dim returnConnString As String
   Dim sMethod, sColumns, sTableName As String
   sColumns = "DataLink, Platform, Login, Password, Server, Database"
   sTableName = "tblzApp"
   sMethod = ""
   If ConfigurationManager.AppSettings.Count > 0 Then
       sMethod = ConfigurationManager.AppSettings.GetKey(0)
   End If
   Try
       Select Case sMethod
           Case "ConnectionString"
               returnConnString = ConfigurationManager.AppSettings(sMethod).ToString
           Case Else
               Return sMethod
       End Select
       Return returnConnString
   Catch ex As Exception
       ex.Source &= "<br /> DAL.GetConnectionString"
       Throw ex
   End Try
End Function

Just for clarification, this is a 23 line function that should be a 1 line function. Here is what the body should look like:

Return ConfigurationManager.ConnectionStrings("MicroMain")

The beauty of this 1 line function is that if it fails, you know exactly why it failed. It fails fast. Conversely, their code fails slowly. In other words, it failed but didn't tell us why.

In addition to that, I happened upon at least 9 different code smells within this single function.

Code Smells within GetConnectionString

  1. getting a key/value item by position instead of name (appSettings is a key/value store)

    This is the equivalent of being a high school principal and walking into a classroom to fetch Jonnie. Instead of walking in and asking for Jonnie, you walk in and grab the student closest to the door, whisper into his ear "Are you Jonnie?". If he says "no", you walk out the door and do not complete your objective.

  2. using AppSettings for the connection string instead of ConnectionStrings (non-idiomatic)

    Since 2005, .net has a config section dedicated to connection strings.

  3. declaring unused variables (ie copy and paste programming)

  4. declaring unnecessary temporary variables (eg returnConnString)

  5. unnecessarily calling ToString

    Getting an AppSetting value implicitly returns a string. Calling ToString simply gives you the opportunity to fail with the generic error message "object not set to instance of object" instead of letting the caller handle the missing value case.

  6. try/catch is totally unnecessary (since ToString should not be called)

    Furthermore, try/catch blocks should not be put into most methods. Unhandled exceptions should be allowed to pop up the stack to a global exception handler.

  7. mixing html into data access code

    If I have to explain why this is bad, you need to find another career.

  8. commented out code still hanging around (lazy coding or perhaps they don't use source control!!!)

  9. naming the connection string key "ConnectionString" instead of "MicroMainConnectionString"

    This assumes that the application is the only application deployed on the server.

The disaster continues

  • no global exception handler (ie yellow screen of death)
  • SQL Injection attacks

    Looking through other methods within their code, I found them not using parametrized queries. Instead, they were building SQL by string concatenation which leaves them wide open to SQL injection attacks.

Makes you think...

Looking at their website and taking into account the fact that they sold their software to Newell-Rubbermaid (a Fortune 500 company), I get the impression that they have better salespeople than developers. Their code was head-scratchingly bad. It makes you wonder about the state of code in other off-the-shelf applications. Is it all this bad, or was this an anomaly?

As Jeff Atwood would say "Enterprisey to the bone".

Saturday, August 6, 2011

Alaska: The Last Frontier

Skip to the Photos

As I left work the Monday after returning from Alaska, I realized exactly who I resembled; Al Pacino from end of Insomnia. Fitting since that movie was set in Alaska. Alaska will do that to you. Especially in the summer when it stays light out almost all day long.

That fact was the first thing that struck us on our trip. While we were in Fairbanks we could look out our hotel room at 12:30AM and still see all the way across the town. It wasn't until we drove farther south into Homer that we were awake while it was dark outside.

From Alaska

Most Alaskans are very similar to "Americans" as they call us lower48ers. However, there are some notable differences.

One difference is gun ownership. Most Alaskans own, carry, and use guns on a regular basis. This is a big difference from your average Northern Virginian; At least the ones I associate with. Heidi's (my wife) grandfather has a huge gun collection. In fact, he keeps a vintage, working condition 1848 Sharps rifle under the couch in his living room. That discovery seemed astonishing to me; Both that he owns such an antique and that he keeps it under his couch. He also has a working 1898 Winchester shotgun in his kitchen resting against the counter. Heidi's uncle has a AK-47-like clone casually resting against the bookshelf in his living room. So it is a different culture from what we are used to here.

I don't know if most Alaskans also identify themselves as "westerners", but our experience indicated that they share similar traits. One such trait was an assertiveness with strangers. Whereas eastern Americans are often considered to be closed off to interacting with strangers, Alaskans are not. We met a lot of people in public areas who simply started talking to us. To me, as someone is as reserved as any easterner, this took some getting used to. My wife loved it. She's more outgoing. Perhaps this phenomena was simply a function of us spending most of our time in high traffic tourist areas. The sort where the locals are wont to give suggestions. However, often it wasn't. During our last night in Alaska, we were at a bar in Anchorage sitting a long, high table when a guy and his girlfriend sat down next to us and started up a conversation. They weren't giving us suggestions or selling us anything. They simply wanted to talk. That type of experience seems a lot more unlikely to happen in Virginia.

From Alaska

Seeing wild animals native to Alaska was one of the best ongoing experiences we had. The interesting animals we saw included: moose, bald eagles, a sea otter, and orca whales (killer whales).

Moose are like the Alaskan deer. The are everywhere along the side of the road in Alaska.

We saw the orca whales the first night we stayed in Homer. We were on the "Spit". The Spit is a 3 mile narrow strip of land that juts out from the town. We had just exited the famous Salty Dawg bar when Heidi says, "let's walk down to beach". So we walk down and stay just long enough for her to put her feet in the water. We turn to walk back when she catches a glimpse of something briefly pop up out of the water about 30 feet from shore. I sort of see it. She said, "I think those were orcas". I said, "What's an orca?". So we stood there for a second and sure enough, the two whales pop back up briefly. Their dorsal fins and black color where unmistakable.

Our trip was split into two halves. The first half was spent with Heidi's family. The second was more of a personal vacation for us. Most of Heidi's family lives in Palmer, Alaska. Palmer is about 45 minutes away from Anchorage. For you Palin fans or haters out there, Palmer is 5 miles away from Wasilla. We spent a couple of days there, then we drove to Fairbanks which is about a 6 hour drive away. We were in Fairbanks for Heidi's cousin's wedding. After leaving Fairbanks, we stayed with Heidi's aunt and uncle in their cabin located between Delta Junction and Tok. After staying with them for a couple of days, we returned to Palmer via Tok. This is the point in the trip when Heidi and I left her family and went on our own. We traveled south onto the Kenai peninsula after first staying one night at Alyeska resort in Girdwood. Our journey south brought us to Homer where we stayed for two days. After that, it was time to travel back to Anchorage and then back to Virginia.