Larry Price

And The Endless Cup Of Coffee

Setting Up a Go Environment in Ubuntu

| Comments

Update Jan 17, 2015: It’s 2015 and things are different. Check out my updated post on managing Go dependencies for a better solution.

Some very light cajoling led me to do some investigation into Google Go (often called golang for ease of internet search). This is a brief recounting of how I got up and running on Ubuntu (first 12.04 and then 13.10). Luckily, this has been made espcially easy for us with the introduction of a golang package in the Ubuntu package repositories. There are also official installation instructions if you don’t like mine.

Open up a terminal and let loose:

1
$ sudo apt-get install golang

The download is pretty heavy, so this step may take some time. Eventually the installer for golang-go will ask you if you want to “Report installation of public packages to Go Dashboard.” I’ve been choosing “No” to this question and have no complaints.

Now comes the fun part. Serious Go development relies on having a “workspace” setup involving a specific directory structure including bin/, pkg/, and src/ directories. Google’s official set-up page contains more information about these workspaces.

I’m not a big fan of putting a visible directory in $HOME, so I opted to make a hidden directory called .go. After creating the directory, the environment variable $GOPATH needs to be set and $PATH needs to be adjusted.

1
2
3
4
5
$ mkdir ~/.go
$ echo "GOPATH=$HOME/.go" >> ~/.bashrc
$ echo "export GOPATH" >> ~/.bashrc
$ echo "PATH=\$PATH:\$GOPATH/bin # Add GOPATH/bin to PATH for scripting" >> ~/.bashrc
$ source ~/.bashrc

Now I’m going to create a go project and add a link to it in the workspace I just created.

1
2
3
$ mkdir -p $GOPATH/src/github.com/user
$ mkdir ~/hello-go
$ ln -s ~/hello-go ~/.go/src/github.com/user/hello-go

For some actual test code, I’ll add a file in my hello-go/ directory called hello.go with the following code:

hello.go
1
2
3
4
5
6
7
package main

import "fmt"

func main() {
  fmt.Println("Hello world")
}

Now I’m going to install the binary created from compiling this code into my $GOPATH to verify that my workspace is set up correctly, then I’ll run it to behold the fruit of my efforts.

1
2
3
$ go install github.com/user/hello-go
$ hello-go
Hello world

Installing is not necessary every time I want to test that my code compiles; running go build in the source directory will create a local executable that can be executed for incremental testing.

If you’re interested in learning golang, I would recommend doing the go tour. It goes way beyond a trivial hello world program and gives you some insight into many coplex go concepts (I even posted my solutions as a gist, if you’re interested).

Tell Your Users When You Fail

| Comments

Your users put a lot of faith in you. They put up with your terrible design, your horrible taste in color scheme, and your ability to take up over 100% of their computer’s memory. With that in mind, don’t these poor people deserve a little bit of honesty?

I came across some code recently that irked me. This code asks for a handle to a database abstraction class and then runs a query on it. It looks kinda like this:

settings.rb
1
2
3
4
5
6
def changeSettings(newSettings)
  db = dbFactory.get("settings.db")
  if !db.nil?
    db.execute(buildSaveQuery(newSettings))
  end
end

How nice that changeSettings doesn’t try to play with a nil database, right? But what about the user’s data? It wasn’t saved. And no one knows. Not even you. Now, maybe the user will happily continue what he’s doing until he notices that his new settings aren’t quite right. So he goes back to them again. Same result. Repeat ad infinitum.

How I would initially approach this is to add an else statement that launches a dialog giving some useful data to the user. Whatever you do, for the love of code, DO NOT tell the user that you had database problems. For most applications, the user will have no idea what that means. It might look something like this:

settings.rb
1
2
3
4
5
6
7
8
9
10
11
12
def changeSettings(newSettings)
  db = dbFactory.get("settings.db")
  if !db.nil?
    db.execute(buildSaveQuery(newSettings))
  else
    showDialog(title="Save Failed!",
               msg="I'm sorry, but your data could not be saved." +
                   "Press 'Try Again' to give it another go." +
                   "If the problem persists, restart the application" +
                   " or contact system support.")
  end
end

This is not a bad solution. But what about all the other places in the code I get the database from the factory? I’d have to update those as well. It would be better to be able to code the factory to launch a similar error dialog whenever this happens. Even better, let me hand the factory a reference to an appropriate dialog whenever I call dbFactory.get.

Another much more frightening possibility is to skip the nil check. Can you guarantee that dbFactory.get will never be nil? In that case, this option is actually pretty good.

Even if that’s not a guarantee you can make, it may still be a valid solution. Crash early before you do too much damage. Now, if there’s some kind of crash-handler or global exception-catcher in your application, then you can catch the impending crash and tell the user the application needs to be restarted… And the app probably needs to be restarted anyway! There’s no need to keep running after you’ve reached some horrible error state that needs to be addressed.

Just do something! Your users (especially if that happens to include me) will appreciate your honesty, even if it’s so brutal that they have to restart the application.

Login Shell Not Sourcing .bashrc: A Brief Lesson in Dot-files

| Comments

I have a confession: I’ve been avoiding using rvm for the past few weeks for stupid reasons.

When using rvm with gnome-terminal, I have to tell gnome-terminal to run as a login shell so that /etc/profile is sourced. The login shell is then supposed to source $HOME/profile, which is then supposed to source $HOME/.bashrc. Installing rvm results in me editing my .bash_profile to add the following line:

.bash_profile
1
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

All my rvm environments seem to work, so this is a success, right?

Well, I type the good ol' ls command and I notice that all my colors are missing. I notice that the terminal title no longer reads the present working directory, but instead greets me with a disinterested “Terminal.” What happened?

Eventually I realized that this was a problem caused by not sourcing my .bashrc. Where did I go wrong?

The login shell sources $HOME/.profile UNLESS $HOME/.bash_profile exists, in which case it only sources the latter. So what are the contents of my $HOME/.profile?

.profile
1
2
3
4
5
6
7
8
9
10
11
12
13
# ~/.profile: executed by the command interpreter for login shells.

# [cut for brevity]

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
      . "$HOME/.bashrc"
    fi
fi

# [cut for brevity]

Aha! The sneaky dot-file actually sources $HOME/.bashrc, and my shiny new $HOME/.bash_profile doesn’t. I fixed this by sourcing $HOME/.profile in $HOME/.bash_profile.

.bash_profile
1
2
[ -f "$HOME/.profile" ] && source "$HOME/.profile"
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

For the memory-impaired: .bash_profile sources .profile sources .bashrc.

Re-open gnome-terminal to find my colors are fixed, my title is correct, and rvm plays the right notes. The world is at peace once again, and I don’t have to avoid using rvm.

Hooks in Cucumber-cpp

| Comments

A few months ago I blogged about tags in cucumber-c++. The scenario I presented involved using tags to call a BEFORE hook before the first scenario and an AFTER hook after the last scenario. The code looked a little bit like this:

DoStuff.feature
1
2
3
4
5
6
7
8
9
10
@first
Scenario: Do it my way
  ...

Scenario: Don't do it
  ...

@last
Scenario: Do it your way
  ...
DoStuff_StepDefinitions.cpp
1
2
3
4
5
BEFORE("@first") { cout << "This is the first step!" << endl; }

AFTER("@last") { cout << "This is the last step!" << endl; }

...

The scnenario labeled @first would call the corresponding BEFORE macro and the @last scenario would call the AFTER macro. If I didn’t have tags in place, the macros would have both been invoked before/after each scenario. Macros for BEFORE_STEP and AROUND_STEP are also available; BEFORE_STEP allows you to tag individual steps and AROUND_STEP acts as a before/after for individual steps.

This was a workaround. What I really wanted to do was to not use tags, and instead unconditionally perform an action before the first scenario was run and after the last scenario is complete. Since cucumber-cpp is open source, I decided to implement that a few weeks ago (see changeset). Now the above example becomes:

DoStuff.feature
1
2
3
4
5
6
7
8
Scenario: Do it my way
  ...

Scenario: Don't do it
  ...

Scenario: Do it your way
  ...
DoStuff_StepDefinitions.cpp
1
2
3
4
5
BEFORE_ALL() { cout << "This is the first step!" << endl; }

AFTER_ALL() { cout << "This is the last step!" << endl; }

...

This is the same behavior as the first example, except I don’t have to force my fellow developers to move tags around when they add/remove scenarios. Also now my fellow developers can stop asking me why I was using tags and why when they added a scenario they couldn’t get the tests to pass.

The moral of the story is that you should go implement that feature you want to see in your favorite open source project.

SEP Blog Battle: Tools of the Trade

| Comments

To whom do I owe any programming success I may have in a given day? My education? My wonderful peers? The shriveled wad of grey goo in my head? None of the above.

My search engine. DuckDuckGo. Google. Wikipedia. Hardly a problem exists that can’t be assisted in some way by a quick search.

How do I use Google Go (answer)? How do I use tags in cucumber-cpp (answer)? How do I brush my teeth without toothpaste (answer? What’s the deal with airline food (answer)?

It’s all so easy. It’s right at your fingertips. A proficient programmer these days has to also be a proficient “Googler.” However, a programmer’s job description is not “copies all code from the internet.” Although the odds are high that someone has had a problem very similar to yours, you need to be able to take that code as an example and adapt it to your current situation. If that weren’t the case, I think we’d be losing our jobs to high school kids pretty quickly.

So at the end of the day, make sure to be thankful to your search engine. Buy it flowers, make it dinner, rub its feet; just let it know how much you appreciate all the hard work it does for you when you do nothing but ask it silly questions all day.