Using Variants in Rails 4

I’ve been using Variants in Rails 4 to change my layouts for one controller action. It’s really straightforward – just set the variant name as a symbol, for example:

request.variant = :popup

Then name the template file with the variant name in it, e.g.

new.html+popup.haml

Another neat trick I discovered is that you can also use the variant to control the layout file. I wanted to have a different layout for my popup content, one that didn’t include all of the usual bumph like headers and menus. Turns out I didn’t need any other code, just create a template in my layout folder with the variant:

website.html+popup.haml

In addition to that, I can also use it with partials. Inside my haml file, I reference a partial as I would normally, and when the variant is set, it automatically chooses the partial with the variant if there is one.

...
= render partial: 'customer' 
...

Now I can use the popup variant across multiple controllers with this same simple layout.

I also discovered that setting variant to nil causes a problem. I wanted to do this:

request.variant = find_my_variant
...
...
...
def find_my_variant
  return nil if some_logic_determining_no_variant
  :variant_name
end

Instead I have to do this:

request.variant = find_my_variant unless find_my_variant.nil?
...
...
...
def find_my_variant
  return nil if some_logic_determining_no_variant
  :variant_name
end

I’m interested to know if there is a way to set a “blank” or default variant so that I can remove that extra check …

Try and Fetch

One of my colleagues showed me this awesome little method in Rails called try.

How many times have you written code to check for nil like this?

def get_value
  if @my_object.nil?
    ""
  else
    @my_object.value
  end
end

(well I have, many times!)

If you call try on an object if you’re not sure whether or not it will respond to that method. If it doesn’t, then you just get back nil:

def get_value
  @my_object.try(:value)
end

Particularly useful if you want to call a method on something you get back from a hash that may not be there:

@my_object[:my_key].try(:method)

While reading up on this, I also discovered the fetch method for Hashes, which allows me to specify a default value to return if the key is missing.

This means I can clean up stuff like this:

my_array = @my_hash[:my_key]
my_array.each {|array_item| ... some code ... } unless my_array.nil?

To this:

@my_hash.fetch(:my_key, []).each {|array_item| ... some code ... }

Less if statements, less branching, and so hopefully fewer bugs to write!

Upgrading to RSpec 3

I recently upgraded our Rails application to use RSpec 3, which is currently in its second beta, from 2.99. I was expecting it to be nice and straightforward, but sadly it was not! This was partly because we have been using RR for mocking and stubbing, and the syntax was not compatible with RSpec 3.

In the process of upgrading I learned a bunch about the new RSpec “allow” syntax, which in my opinion is far nicer than the RR one we were using.

Here’s how to stub:

allow(thing).to receive(:method).with(args).and_return(other_thing)

Mocking can be done in the same way by substituting “allow” for “expect” – although in most cases the tests read better if you test that the stub received the method using the following matcher:

expect(thing).to have_received(:method).with(args)

That this is different to the previous RR syntax, which was expect(thing).to have_received.method(args)
You can also use argument matchers, for example:

expect(thing).to have_received(:method).with(a_kind_of(Class))

And you can verify how many times a method was called:

expect(object).to have_received(method).at_least(:once)
expect(object).to have_received(method).exactly(3).times

The .with(args) and .and_return(other_thing) methods are optional. You can also invoke a different function:

allow(thing).to receive(:method) { |args| block }

Or call the original function:

allow(thing).to receive(:method).and_call_original

Another thing we used fairly often was any_instance_of. This is now cleaner (RR used to take a block):

allow_any_instance_of(Class).to receive(:method).and_return
allow_any_instance_of(Class).to receive(:method) { |instance, args| block}

If you pass a block, the first argument when it gets called is the instance it is called on.
In RSpec 3, be_false and be_true are deprecated. Instead, use eq false or eq true. You can use be in place of eq, but when the test fails you get a longer error message, pointing out that the error may be due to incorrect object reference, which is irrelevant and kind of annoying.

Using RSpec mocks means that we can create new mock or stub objects using double(Class_or_name) rather than Object.new, which results in tidier error messages and clearer test code.

Stubbing a chain of methods may also be a handy tool – I only found one place where we used it, but it is useful if we’re chaining together methods to search models.

allow(object).to receive_message_chain(:method1, :method2)

More info:

  1. https://relishapp.com/rspec/rspec-mocks/docs
  2. https://github.com/rspec/rspec-mocks

Update: it turns out I was missing a configuration option in RSpec. It should have worked with RR by doing this:

RSpec.configure do |rspec|
  rspec.mock_with :rr
end

Thanks Myron for clearing this up :)

Scala – Day 1

I was looking forward to Chapter 5 of Seven Languages in Seven Weeks: Scala. I’ve heard quite a bit about it in the last few weeks at various user groups, and I’m hoping to get my hands on it at some point in my upcoming work with Atlassian, so this was a good time to dive in. As a personality, Scala is assigned Edward Scissorhands in the book: “awkward, and sometimes amazing”.

I tried at first to install it with Homebrew, which just failed with a 404, so I downloaded the package and installed it manually, which worked fine.

Day 1 was pretty straightforward – type a few things into the console and have a look at what you get back. This chapter delves into loops and ranges and compares Scala with both Java and Ruby, finishing up with some simple class definitions and traits. As with most of the chapters so far, it very quickly introduces a lot of ideas – not much detail, but enough to get me thinking.

In the self study for Day 1, the first questions are reasonably simple.

  1. Here’s a link to the Scala API
  2. There are lots of blog posts comparing java to scala, mostly just one aspect. I liked this write up based on a year of experience with Scala.
  3. A discussion of val versus var.

The next challenge was to write a game that will take a tic-tac-toe board (noughts and crosses for the Brits …) and determine a winner. The bonus part of the challenge would be to make it into a game that two people could play, so I attacked this part first.

I started off using Sublime Text 2, then decided to switch to IntelliJ with the Scala plugin. I like Sublime, but was hoping IntelliJ would give me better auto completion, refactoring tools and keyboard shortcuts. It seems to work OK – I had to point IntelliJ towards my Scala installation, and it is still popping up with some errors although it does compile and run just fine. Perhaps in Day 2 and 3 I’ll dig into those a bit more.

In writing the code for the game, I tripped up on a few things. I had Martin Odersky’s book Programming in Scala to refer to as well, which helped me solve most things really quickly.

Firstly that the chapter hadn’t covered how to return a specific type from a function. Scala doesn’t require the return keyword, but if you don’t specify a return value, it returns Unit().

Here’s a function without a return type:

def myMethod() {

}

And with:

def myMethod() : Int = {

}

In my next mistake, I tried to create an array and then add items to it – Arrays are mutable in Scala, but you can’t change the size of them. I didn’t even have a good reason for doing this, except that I thought it would make the code prettier, so I changed it to a List (immutable) instead. And it looked fine :)

I don’t know a lot about functional programming yet, so I did have a couple of classes in my solution. I wanted to make sure I had no mutable objects though.

When I finished my initial solution, I had three files – I ended up taking the lazy way of copying all the classes into the one file and running it from the terminal with scala tictactoe.scala. Here’s the initial attempt. I like that it doesn’t have any mutable objects, it’s simple, I don’t have to worry about blanks, and the simple map method to get the positions. I don’t much like the magic winning combinations in the Judge class, and I don’t like that if you don’t enter the moves in a valid format it will barf.

Next challenge: on to Day 2, and also trying to extend the tic-tac-toe game for the bonus challenge!

Finishing up with Io

As I reached Day 2 with Io, I continued to struggle with the syntax, in particular temptation to write object.method instead of dropping the ‘.’. I felt that I was starting to get some of the concepts of the language, the ability to rewrite core methods and override Operators.

However, I have also struggled throughout Day 2 and Day 3 with the lack of easily available documentation – the reference and guide on the main IO website did not seem to explain many of the things I needed to know, including how to read input from the console. I resorted in some cases to “cheating” by reading other people’s solutions to the exercises (although it’s not really cheating, since the point is to learn :)).

As I wrote my solutions, particularly the longer ones, they felt slightly clumsy – as though I wasn’t taking advantage of Io’s strengths. In the middle of Day 2 and start of Day 3, I really wasn’t enjoying working with the language, although by the end of Day 3 when I introduced the new Xml_Element object, it felt more natural. I’m glad I finished the chapter, although I’m still not really sure where I would use Io.

Overall, the main thing I’ve got out of the book so far is a greater understanding of meta-programming, which I’m hoping will help me take better approaches to new programming problems.

All of my solutions are on Github Gists:

Here are some highlights from the difficulties I ran into …

I was baffled for Day 2, Exercise 2 as to how to keep the original division method, but a quick internet search (and a minor cheat) revealed the solution: I needed to store the original division method in another variable:

When I reached Exercise 7, I discovered from other solutions that serialization in IO is actually really, really easy. All objects have a serialized method that writes it out to a string. When reading the object back from a file, all that was needed was the assign the results of the doFile("filename.txt") method to a new object. Writing to files is easy too – here’s the full solution:

For Exercise 8, I spent a considerable amount of time trying to find out how to read input from the console – turns out you can use File standardInput readLine. This gives you a string, so you need to use asNumber to complete this exercise.

Day 3, Exercise 1, was a massive struggle – at first I could not figure out how to pass the right indent, and I ended up looking around at some other examples before I figured out that I needed to:

  1. Write the parent node
  2. Add one to the indent
  3. Process the child nodes
  4. Remove one from the indent
  5. Close the parent node

I also discovered that using indent := indent + 1 doesn’t work – I guess you lose the reference to indent, so you need to do indent = indent + 1. Here’s the finished code:

In Exercise 2, I discovered after some internet searching and experimenting that Io has two built in methods: curlyBrackets (as used in the book) and squareBrackets – these can both be overridden to allow lists or maps, or anything else, to be created using {} or []. I guess this might be obvious to some people, but I was quite confused by it!

Here’s the list code:

The final exercise, adding attributes to the XML Builder, had me stumped for some time – in fact, I took a break from it overnight and a solution came to me in the shower :) My difficulty was figuring out when to write the contents of the XML node, I didn’t want a separate method but couldn’t write out the contents inside the loop.

The final solution still feels slightly clumsy but it does work (indents and all):

Seven Languages Week 1: Ruby

Week one of the seven languages is complete!

Having the support of the study group was great – motivating but without being too much. I was amazed at the breadth of the solutions, especially to the homework for Day 1 and Day 2.

Day 3, I was a bit underwhelmed by – the final part of the chapter introduced a lot of interesting techniques with meta-programming and modules, but the problem set didn’t really seem to challenge me to think too much about them.

The book encouraged me to look at the API to try and find solutions for different problems. Having the study group made this aspect even better, because we often found different things – for example, collect and zip methods for arrays. James in particular found some very short and neat ways to solve the problems.

Overall I think I like Ruby even more after doing this. It has so much “syntactic sugar”, and I definitely have a sweet tooth! Overall I’ve learned that while you can use Ruby to write programs in a rather boring, more Java-esque style, there is almost always a much neater, Ruby-ish way of doing it. I only wish I had more time and opportunities to learn it properly.

My highlights:

  • Day 1 reminded me of the usefulness of ranges
  • Quick ways to convert between hashes and arrays in Day 2:
  • Discovering the ‘grep’ method in Enumerable from James’ day 2 solution.
  • Finally getting a better understanding of modules (still far from perfect, but I definitely get them far better than before)
  • Learning the ‘zip’ method for arrays – although still not sure I completely understand how to use it!

My solutions are here: https://gist.github.com/jocranford

7 Languages in 7 Weeks – The Next Study Group …

I was inspired a while ago by Daniel Temme’s experience working through the book Seven Languages in Seven Weeks as part of a study group organised by Aimee Daniels, and together with James Doig (a colleague and regular pair on my current project!) we decided to start a new one. We’ve got a Google group and planning to use Google+ hangouts, blogs and twitter (with the tag 7languages7weeks or through this account).

We’ve agreed to kick off on October 24th with Chapter 1, which covers Ruby. I’ve had a sneak peek at the book, a bit of a giggle at the comparison of Ruby the programming language to Mary Poppins, the magic British nanny, and I’m excited now to get started. I haven’t done very much functional programming, and the book promises to challenge me, and to teach interesting aspects of each language. We’ve agreed to take it a little slower for the first couple of chapters and see how things go.

Our group has grown to around fifteen people, divided about half and half between ThoughtWorkers and Skyscanners, and also includes one post-technical project manager – very impressive! There’s still time to join, so please leave a comment or contact me via twitter if you’re interested.

Running JSLint with Node

As part of some recent work on an open source project, I’ve been tinkering with node.js. When starting a new javascript project, I like to set up tools like JS Lint early on, since fixing lots of errors later is tedious. I wanted a simple script to run it within node – searching the interwebz revealed a couple of options to run on a single file, so I adapted a couple to do what I wanted.

The result is on github and below – I added just one line to the Crockford script:

exports.JSLINT = JSLINT;

The jslint-runner file sets up options and hooks into node, then loops through all the files in a directory and lints them one by one. It’s not recursive (I didn’t want it to be) but that could be easily added in. The predefinitions include jasmine keywords.


var options = {
    node: true,
    predef: [
            "jasmine",
            "describe",
            "it",
            "expect",
            "beforeEach"
    ]
};

var ANSIColors = {
  pass:    function() { return '\033[32m'; }, // Green
  fail:    function() { return '\033[31m'; }, // Red
  neutral: function() { return '\033[0m';  }  // Normal
};

var stringWithColor = function(str, color) {
    return (color || ANSIColors.neutral()) + str + ANSIColors.neutral();
  }

var fs = require('fs'),
        sys = require('sys'),
        dirName = process.argv[2],
        readFile = function (name) {
            return fs.readFileSync(name).toString();
        },
        print = function (message) {
            sys.puts(message);
        },
        quit = function (code) {
            process.exit(code)
        },
        jslint = require('./jslint');


if (!dirName) {
    print("Usage: jslint.js directory");
    quit(1);
}

fs.readdir(process.cwd() + "/" + dirName, function(err, list) {
    list.forEach(function (file) {
        var fileExtension = file.substr(file.length - 3);
        if (fileExtension === ".js") {
            doLint(dirName + "/" + file);
        }
    });
});

var doLint = function(fileName) {
    var e,i,input;
    input = readFile(fileName);
    if (!input) {
        print(stringWithColor("jslint: Couldn't open file '" + fileName + "'.", ANSIColors.fail()));
        quit(1);
    }
    if (!jslint.JSLINT(input, options)) {
        print(stringWithColor("Problems in " + fileName, ANSIColors.fail()));
        for (i = 0; i < jslint.JSLINT.errors.length; i += 1) {
            e = jslint.JSLINT.errors[i];
            if (e) {
                print('Lint at line ' + e.line + ' character ' +
                        e.character + ': ' + e.reason);
                print((e.evidence || '').replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"));
                print('');
            }
        }
    } else {
        print(stringWithColor("jslint: No problems found in " + fileName, ANSIColors.pass()));
    }
};


Agile 2006: The Planning Game – Chet Hendrickson & Ron Jeffries

Tuesday 09:00-12:30

Abstract

This is a simulation of an agile project, to demonstrate the impact in business value of releasing earlier, the importance of knowing business priorities in order to get the most value and using velocity to estimate release dates.

Summary

This was one of the highlights of the conference for me. Ron and Chet have played this game over and over, and it clearly shows – it’s funny, it works like clockwork, and the messages reveal themselves through the game without needing to be called out. If you haven’t played the Planning Game, and you get a chance to attend one of their sessions, don’t miss it.

The planning game simulates the planning of an agile project. We are told that this project must be completed within six months. There are forty five “story cards”, each numbered, with different numbers in each corner, and our first task is to arrange them in six columns to show management how we will complete the project. Ron and Chet will play the roles of Management, as well as fickle Nature.

We know this is a trick but we can’t figure it out, so we arrange the cards randomly with more at the start and fewer at the end. Along comes Nature and tells us that in our first iteration, we completed four stories. This is disasterous – we had eight planned. The team next to us have completed exactly what they predicted. This is confusing, how are we supposed to know what we can get done?

One of the other teams informs Management that they are unable to complete the project within six months. Management, understandably, is not very happy. “How long do you need?”

“Seven months”, say the team. Hmm. Management decide that one extra month is not too bad, and the team have at least been honest enough to admit that they can’t complete the project on time. “But no longer,” say Management, “or you will be fired. Now plan your next iteration.”

We rearrange the cards for the next iteration, and Nature dictates that this time we once again complete four. We aren’t doing very well here. It’s clear to most people that we can’t complete the project in time. Management are even more impressed with the team who identified this earlier. The rest of us are in the doghouse. How long do we need?

Based on our past performance, we estimate that we need twelve months. With nothing else to go on, we simply use the number of completed stories – 45 / 4 = 11, with one left over. The group average is around nine. The team who asked for seven admit that they actually need longer. Management are not happy.

We break, and try to decode the numbers on the cards, but we can’t. We discuss what Nature was looking at when he came around to tell us what we’d got done. Was he doing some complicated math? We don’t think so. We don’t know. It’s frustrating, but it’s fun, and the lessons are pretty clear. How can you plan projects without knowing how fast you can work?

After the break, Ron and Chet tell us which numbers represents the effort required for the stories, and what our velocity is. Then they give us the chance to replan the project from scratch. Now it’s easy – we can complete in nine months. We argue over which of the stories should go at the beginning and the end.

We eventually put most of the big stories earlier since they represent more effort and more risk, so we should get them out of the way earlier. Then they suggest that each story could have equal value, which would mean we’ve really messed up.

This is another important lesson, and the game drives it home perfectly. We can’t guess the business priorities. If we don’t know them, how can we effectively plan the project?

We finally get this final piece of the puzzle, and they share with us how the value of the stories is represented. Now we can plan properly, and make sure we get the most value for the least effort in the first iteration.

The final exercise is the most powerful. We need to decide when to release.

Ron has created a spreadsheet that graphs the value realized by the business depending on the release date. The logic works like this:

  • Each month, development costs the company x units
  • Each month, the released features generate the company y units
  • Y is the total number of units of value released so far
  • The highest value features are completed in the first iterations

Key points to apply

  • Focus on reducing release time – ultimate goal is to release every sprint to maximize business value.
  • To maximize business value, it’s vital to stack rank stories based on the maximum value realized for the least effort

Agile 2006: Agile/Evolutionary Database Techniques – Scott Ambler

Monday 16:15-17:00

Abstract

Database design and refactoring can be done in an agile and evolutionary way.

Summary

Data is only one of the many important aspects of software development, and rarely a primary one. Agile is developed from the “object” community, and sometimes suffers from a blind spot with regard to database development.

Databases can be built incrementally, with an evolutionary approach within the agile model. At the start of the project, spend around ten or fifteen minutes with the business owner to define the database structure at a high level – at this stage, attributes and behaviors are not discussed.

Having a small amount of upfront modeling is useful to avoid major changes later – but it is not necessary to do the amount of upfront modeling advocated by traditionalists.

The database is then built iteratively, evolving in the same way as the objects, with just enough tables and attributes at each stage to support the system. Visual Team Studio for Data Professionals supports this approach for database engineers.

Often expectations of the data community are low, we don’t expect them to be able to do “trivial” things, such as adding a field to a production database. But databases can be refactored while retaining both behavioural and informational semantics – in other words, without messing up the data.

Databases are generally tightly coupled to applications. Refactoring a production database, for example changing a field name, therefore affects a lot of applications. However, it can be done by creating a new field with a new name, using triggers to ensure it is kept up to date, and using a short transition period to allow developers to update all of the applications that will be affected. The “scaffolding code” is then removed.

Coupling is the main enemy of database refactoring – if this can be reduced, refactoring databases becomes more straightforward.

Recommended further reading
Agile Model Driven Development: http://www.agilemodeling.com/essays/amdd.htm