Gray Soft

The programming blog of James Edward Gray II (JEG2).
  • 1

    MAY
    2012

    Single Method Classes

    [Update: I've changed my mind about some of the following due to this excellent counter argument.]

    In the words of Dennis Miller, "I don't want to get off on a rant here, but…"

    There's something that drives me crazy and I see it in so much Ruby code. I see it in the documentation for our key projects; I see Rubyists of all skill levels doing it; it's just everywhere.

    Let's talk about when the use of a Class is and is not appropriate.

    The Chained new()

    Here's an example of one form of code that bugs me:

    class Adder
      def add(n)
        40 + n
      end
    end
    p Adder.new.add(2)
    

    The problem here is that a Class has been used, probably because as Rubyists that's always our default choice, but it's the wrong fit for this code. A Class is for state and behavior. The example above is just using behavior. No state is maintained.

    A handy tip for sniffing out this problem is watching for a call to new() in the middle of method chaining as we have here. If you always use a Class like that, it's not really a Class. Put another way, if an instance never gets assigned to a variable, something has likely gone wrong with the design.

    Read more…

  • 21

    APR
    2012

    Let's Patch Rails

    In celebration of my first ever trip to RailsConf next week I wanted to be a good open source citizen and contribute a patch.

    I'm giving a presentation at the conference on various random features that the framework provides. I selected features from many places like blog posts, books, and some that I just remembered from years of working with the software.

    One of the features I decided to show was an old feature that I never see anyone use. It turns out that there's a good reason for that. When I tried it on a modern Rails, it didn't work anymore. Rails has undergone some changes under the hood and this feature was likely removed in that process. I figured out a workaround so I could still show it in my presentation, but it would be nice if I contributed the fix back to Rails so others could use it.

    In this article, I will walk through the entire process of doing that.

    What's Missing?

    ERb has always had an under appreciated syntax tweak. Everyone knows you can write code like this:

    Read more…

  • 11

    APR
    2012

    Riding the Testrocket

    I say it a lot, but programming is about ideas. More specifically, it's about not running out of ideas.

    Along these lines, I read the results of an interesting study recently. It was a study about how we think and solve problems. When I was in school, the belief was that we needed to cram our brain full of facts. We were pushed to memorize, memorize, memorize.

    The more modern view of learning is that facts don't matter as much. Nowadays we just try to teach children how to think. The assumption is that they can find the facts they need, because information is so universally available, and their thinking skills will allow them to work their way to other bits of knowledge.

    The study looked at people taught using both of these techniques and found some surprising results: us memorizers can often out think the thinkers. A leading theory about why that's the case is that the memorizers have more of a foundation to build their ideas off of. Thinkers may be starting closer to scratch each time. If so, they have further to go to get to the needed solution. Memorizers, on the other hand, may already have a lot of knowledge that puts them closer to the solution before they even need to start thinking.

    Read more…

  • 1

    APR
    2012

    A Stylish Critique

    Before getting started, I feel compelled to point out that my dictionary defines a critique as "a detailed analysis and assessment of something." It seems like we often assume the worst of that word, but that's not how I intend it here.

    The Ruby community seems to be talking about style guides lately. So let's talk about them.

    The fact is that you will have many choices if you go looking for style guides for our favorite language. You can pick from:

    It's obvious that Rubyists care about this topic. Let's see what's out there and consider what really is and is not useful from these guides.

    What is a style guide really, and why do we even have them?

    Defining style guides is surprisingly tough. I suspect they started out as formatting rules for code, but they have evolved pretty far beyond that now.

    Most guides include general conventions that the author feels are important when writing the language in question. This can go all the way down to how to use certain constructs, opinions on what the author considers idiomatic, and syntax to outright avoid.

    Read more…

  • 21

    MAR
    2012

    Learn to Love Mix-ins

    The road to mastering Ruby is paved with understanding some key Ruby concepts. Mix-ins are one of those concepts. I'm sure everyone reading this knows the mechanics of how mix-ins work, but it pays to spend some time really thinking about all that mix-ins imply. Let's do just that.

    Adding a Type

    One of the primary reasons that Ruby needs mix-ins is that it does not support multiple inheritance. That leaves mix-ins as our only option for modeling hybrid objects. It's the way Ruby programmers can add another type.

    That's a good way to think about it too: adding a type.

    Take pagination, for example. Pagination methods are usually defined to return an object like this:

    class PaginatedCollection < Array
      # ... paginated helpers defined here ...
    end
    

    That's never really felt right to me though.

    First, inheriting from Ruby's core classes can come back to bite you in some scenarios. The reason is that Ruby makes some performance tradeoffs to keep the core classes fast, but those tradeoffs mean that those classes don't always perfectly follow Ruby's rules.

    Read more…

  • 11

    MAR
    2012

    When Passion Goes Wrong

    I usually stick to pretty code heavy topics in these articles, but please allow me to take a detour this time. Our industry struggles with a problem that we don't discuss enough and I want to give it some air time.

    The fact is, we're pretty lousy at controlling stress.

    Let's look at why that is and some of the ways this problem manifests. Remember, the first step is admitting that we have a problem.

    We are a Passionate People

    I really believe good programmers are passionate about what we do. Our job can be pretty mentally taxing and, if you don't love it, it would be pretty rough to endure that day in and day out.

    Because of that, we generally find that the programmers who survive the climb are passionate folks. Really think about that for a minute. I'll give some examples.

    Kent Beck is a name I bet most of us know. One of his great successes was actually writing a book of guidelines for how individual lines of code should be structured. He had to care about the individual lines. That's how far he had to go to manage his programming. He's also done a ton for testing, for similar reasons.

    Read more…

  • 1

    MAR
    2012

    The Right Ruby Mix

    Ruby is a melting pot language. It borrows ideas from many things that came before. It combines several different programming philosophies.

    This aspect of the language can be a plus. It means that Ruby is suited to multiple applications. It also opens up some pragmatic shortcuts. Even better, it sometimes encourages us to think about problems using a different lens of thought.

    Of course, this cuts both ways. Ruby living at the intersection of many ideas does have some downsides. First, there's more to learn than you find with some simpler languages. There's a cost for the extra knowledge we have to track. Even worse though, in my opinion, is that it's sometimes hard to know exactly what Ruby's style really is.

    Going Off Script

    One culture Ruby borrowed heavily from is that of the so called "Scripting Languages." The main source of these features was Perl, in my opinion, but you can also find influences from Bash and other sources. I found this comforting since I came to Ruby from Perl, but the truth is that it bothers some people.

    Read more…

  • 22

    FEB
    2012

    Refactoring: The Gilded Rose

    It's time for another refactoring challenge. This time we will attempt a fun problem called The Gilded Rose Code Kata.

    That original description of the problem was for C# developers and it didn't have things us Rubyists love, like tests. Luckily for us though, Jim Weirich ported the code to Ruby and added the tests as he did so. Let's use that version of the challenge.

    As always, I recommend you try the refactoring before you read what I have to say about it. Being familiar with the problem will help you understand what we are dealing with below.

    Setup

    The first step in this problem is to get the code running locally. I started by pulling down Jim's code from GitHub:

    $ git clone https://github.com/jimweirich/gilded_rose_kata.git
    Cloning into gilded_rose_kata...
    remote: Counting objects: 114, done.
    remote: Compressing objects: 100% (46/46), done.
    remote: Total 114 (delta 71), reused 109 (delta 66)
    Receiving objects: 100% (114/114), 15.38 KiB | 13 KiB/s, done.
    Resolving deltas: 100% (71/71), done.
    $ cd gilded_rose_kata
    

    Read more…

  • 11

    FEB
    2012

    Test Driving an Algorithm (Part 2)

    In the last article, I built a quick and dirty solution to PuzzleNode's Hitting Rock Bottom puzzle. I didn't use specs, objects, or even multiple files. In this article, I'll repeat the exercise but using all of those elements. Let's see how that affects the results.

    The Disciplined Approach

    This time, I'll reign in my desire to push forward and solve the problem more carefully, without having to build a fully formed algorithm all at once.

    I still think the input is the right place to start. I need to read in the units. Let's add a spec for that in spec/parser_spec.rb:

    require "minitest/autorun"
    require "stringio"
    
    require "hitting_rock_bottom/parser"
    
    describe HittingRockBottom::Parser do
      let(:units)  { 42 }
      let(:io)     { StringIO.new(units.to_s) }
      let(:parser) { HittingRockBottom::Parser.new(io) }
    
      it "reads the units number from the beginning of the stream" do
        parser.units.must_equal(units)
      end
    end
    

    If you haven't seen the standard stringio library before, it simply wraps a String with an IO interface. That's will allow me to call gets() and other IO methods on it in my implementation. It's perfect for tests like this.

    Read more…

  • 1

    FEB
    2012

    Test Driving an Algorithm (Part 1)

    I want to take a look at some of the differences between Cowboy Coding and Test-Driven Development. To do that, let's solve a problem both ways and see what we can learn from the exercise.

    A Puzzle

    I needed some random problem to solve in this article and the PuzzleNode site is pretty handy for that. Two programmers I've been working with have recently experimented with problem number 11, Hitting Rock Bottom, so I am familiar with it. Let's use that.

    You will probably want to read through the challenge before finishing this article. You may even want to try solving it yourself, just so you'll be more familiar with what I am doing here. The short, short story is that this problem is about simulating the flow of water into a cave for a fixed amount of time and then measuring the depth at each point. It doesn't take too long to solve.

    Setup

    Let's setup a project. I created a few directories and pulled down the data files given with the problem:

    $ mkdir -p hitting_rock_bottom/{bin,data,lib,spec}
    $ cd hitting_rock_bottom/data/
    $ for f in simple_cave.txt simple_out.txt complex_cave.txt
    > do
    >   curl --silent -O \
    >   "http://puzzlenode.com/puzzles/11-hitting-rock-bottom/attachments/$f"
    > done
    $ cd ..
    

    Read more…