Gray Soft

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

    AUG
    2014

    Guard Clauses, Rust Style

    When I'm programming in Ruby, I will often use guard clauses to prevent undesirable scenarios. For example, let's say I'm building a simple Stack:

    class Stack
      def initialize
        @numbers = [ ]
      end
    
      def push(number)
        @numbers.push(number)
      end
    
      def peek
        fail "Stack underflow" if @numbers.empty?
    
        @numbers.last
      end
    end
    
    stack = Stack.new
    
    ARGV.each do |number|
      stack.push(number.to_f)
    end
    
    p stack.peek
    

    If I only want to work with numbers everywhere, I add a line like the call to fail() above. This prevents a nil from being returned from peek(), ruining my expectation that I will have numbers everywhere.

    When I first started playing with Rust, I wanted to write code the same way:

    use std::os;
    
    struct Stack {
        numbers: Vec<f64>
    }
    impl Stack {
        fn new() -> Stack {
            Stack{numbers: vec![]}
        }
    
        fn push(&mut self, number: f64) {
            self.numbers.push(number);
        }
    
        fn peek(&self) -> f64 {
            if self.numbers.is_empty() { fail!("Stack underflow"); }
    
            self.numbers.last()
        }
    }
    
    fn main() {
        let mut stack = Stack::new();
    
        for number in os::args().tail().iter() {
            stack.push(from_str(number.as_slice()).expect("Not a number"));
        }
    
        println!("{}", stack.peek());
    }
    

    Read more…

  • 21

    AUG
    2014

    Asking Better Questions

    I've been playing with some Rust lately and learning a bunch of new concepts.

    As part of my experimentation, I built an RPN calculator in the language, just as an exercise that would require a moderate amount of code to be worked out. Honestly, I don't fully understand everything that I had to do to get this code working yet. Maybe 20% of it came about as me following instructions from what seem to be very helpful compiler errors.

    I wanted to start attacking these concepts that I didn't understand to increase my knowledge. Of course, I was impatient. I had some working code and I knew what I was missing, so I jumped into IRC, pointed at the code, and asked some not-at-all complete questions. All I got was crickets.

    This isn't a failing of the Rust community. It's a lesson I have to relearn every now and then. You have to take the time to present a good enough question that answering it is easy enough and worth it. It's hard work to get your head around 100 lines of code and, even if you do, you'll still be missing plenty of context if the question isn't really well formed. Given that, most people just ignore the question. That's probably for the better too, because any answers provided likely would have missed the points I really needed help with.

    Read more…

    In: Rusting | Tags: Community | 0 Comments
  • 20

    JUL
    2014

    Dave's No Tests Challenge

    I've mentioned before my difficulties in the 2014 IPSC. But taking one beating is no reason not to try again. The first loss just showed me that the contest still had more to teach me.

    A buddy of mine has spent some time with the crossword problem and told me that he enjoyed it. I didn't try this problem during the actual event, but I was a little familiar with it from my friend's description.

    To add to the fun, I decided this would be a great excuse to take up the recent challenge Dave Thomas gave to the Ruby Rogues: "Stop writing tests."

    Step 1: Feedback Loops

    Without tests to guide me, I really want to see what's going on. One of the biggest advantages of tests, in my opinion, is the feedback loop it provides. So I set out to provide my own feedback.

    Since the problem at hand involves filling in a crossword board, the easiest feedback loop I could think of was to see the board as it fills in. The final board is also the required output. Therefor, I decided a good first step would just be to read the board into some data structure and write it back out. Once I had that, I could insert code between those steps to fill it in. And constantly seeing the board evolve would let me eyeball things for obvious mistakes.

    Read more…

  • 10

    JUL
    2014

    One Programmer's Library

    I have always enjoyed the posts where people list out all of the books they think are important, given some subject. They vary wildly. For example, some are very to-the-point while others are rich in detail (and Danielle makes one of those each year).

    I began to wonder what my list would look like. Below I've tried to make those decisions. I was surprised by just how hard it is to restrict myself to the bare essentials. A lot of things that I read influence me in some way.

    The Classics

    I'll start with the super obvious titles you've likely heard mentioned before.

    • Refactoring: Improving the Design of Existing Code is probably the classically great programming text that had the biggest effect on me. This book teaches you how to turn the code you have into the code you want. It doesn't get much more essential than that.
    • Smalltalk Best Practice Patterns is the book I learned a new language just to read. It's worth that. This is The Field Manual of Object-Oriented Tactics and it helps you know what to do line-by-line.
    • Patterns of Enterprise Application Architecture is the book you should read so you can see how much great knowledge we've had about building programs for over a decade. Odds are that this book can teach you multiple strategies for problems you face regularly.
    • The Pragmatic Programmer: From Journeyman to Master is one of those rare books that can make you a better person, in addition to a better programmer. Advice like "Fix Broken Windows" and "Make Stone Soup" have universal scope. This is a must read.
    • Programming Pearls (2nd Edition) is a book about algorithms and, eventually, all programmers need to learn some algorithms. The upside of this title is that it's fun from page one. That helps to keep you interested in what can be a dry topic.
    • Growing Object-Oriented Software, Guided by Tests is almost surely the single biggest influence on how I do Test-Driven Development. There are other schools of thought but pick one and dig deep enough into TDD until you're confident about when and how to use it. This is a tool everyone needs in their toolbox.

    Read more…

  • 26

    JUN
    2014

    IPSC 2014 Postmortem

    I decided to give the Internet Problem Solving Contest (IPSC) a go this year, with a couple of friends. I've done it in the past and enjoyed it. I like how it only eats a few hours one day and I like how the variety in the problems they give you keeps things interesting.

    That said, my performance in the IPSC this year is probably best described as, "Three strikes and you're out!" I did terrible.

    I solved one very simple problem. I spent the rest of the contest chasing after a much harder challenge that I couldn't complete in the time allowed.

    The worst part is that I made some silly mistakes that I've learned to avoid in the past. As penance, I offer up this article, mainly as a reminder to myself, but hopefully also as a tool that could save others from some of my folly.

    Let's start with a simple mistake I made…

    Not All Problems are Programming Problems

    The IPSC does a great job each year of reminding us that some problems are trivial to solve without programming. It's a good thing they do too, because I seem to need a lot of reminding.

    Read more…

  • 30

    MAY
    2014

    Objectified Beer

    I got another thing out of my recent conversation with Katrina Owen: a will-not-let-go itch to try a programming exercise that she mentioned. I'm such a sucker for a challenge.

    Katrina spoke of an assignment that her and Sandi Metz have used in their object orientation trainings. She said that they build an OO implementation of the 99 Bottles of Beer song, "mainly removing ifs and such." There may be more to the actual task than this, but I ran with that brief explanation.

    As I often say, you'll probably learn more by trying the exercise for yourself before you read through my thoughts about it. Give it a go if you can spare the time.

    Diff Driven Development

    I decided to throw some scaffolding into the master branch of a Git repository. I figured I could then branch off of that with each idea, to keep trying things out.

    I started by constructing a trivial framework for running and verifying the song. That consisted of an executable:

    #!/usr/bin/env ruby -w
    
    require_relative "../lib/bottles_of_beer"
    
    verses = ARGV.first =~ /\A\d+\z/ ? ARGV.shift.to_i : 99
    BottlesOfBeer::Song.new(verses).sing($stdout)
    

    Read more…

  • 28

    MAY
    2014

    Are We Teaching the Best Things?

    I'm in Denver right now, mostly to see family. Being the geek that I am though, you know I snuck a little time for the local Rubyists. One of those Rubyists that I was lucky enough chat with is Katrina Owen.

    I always love getting a chance to talk with Katrina. She's so thoughtful that she raises the level of discourse and makes me feel smarter. Plus, it turns out that Katrina and I have been thinking about similar things lately.

    For my part, I've been thinking about the various students that I've taught to program over the years. I have taught many and because they all learned from me, they learned roughly the same way. What's interesting to me is how different the results have been from that technique. In some cases my students were all set after our lessons and they just began coding up a storm. Other students didn't seem to feel they were ready yet though. They had more of a "Now what do I do?" attitude at this stage.

    Katrina raised a similar point from her time teaching in a developer school. When they would get to teaching language basics, they would show several constructs and how they are used. This is similar to how I teach. Just as I have observed, this works for some students. They can just take what they know and run from here. But they also found other students felt a little lost at this point.

    Read more…

  • 17

    MAY
    2014

    A Library in One Day

    I was super inspired by Darius Kazemi's recent blog post on small projects, so I've been looking for ways to speed up my process.

    Today, I tried an experiment: develop a library in one day. I wanted to go from an empty repository to a published gem that I could start using.

    Mission accomplished.

    Topic

    Obviously, I had to select a pretty simple idea to use. I wouldn't have time to do a huge project.

    I think this may be the killer feature of this technique.

    On one hand, you could argue that what I built may not be very library worthy. It's around 50 lines of code. It has ten specs and they really cover what it does. This isn't a complex beast and you could pretty easily hand roll a solution to replace it.

    But in some ways that's the best part. I've dropped a 50 line pattern that I like down to a one line Gemfile include. I'm making it even easier for myself to get some mileage out of experimenting with this code. I can mix and match this new library with other small tools to build up the ecosystem that I want for a project. Plus, if it turns out to be something I regret, it's not like I'm tied down to a huge dependency when I go to rip it out. This thinking actually has me wanting to keep this library minimal, at least for now.

    Read more…

  • 9

    MAY
    2014

    Proof of Life

    As many of you noticed, and some of you regularly messaged me about, this blog has been offline for quite some time. There are many reasons for this: I was rewriting the software this blog runs on, the host that served it closed their doors, I had to take an extended break in working on it for multiple reasons, and, when I got back to it, my half-complete rewrite had enough bit rot that I decided to start fresh. The good news is that all of that mess has finally passed. As you can see, that means this blog is back is business.

    If you are a long time reader and you have a good memory, you'll notice that I changed the name of my blog. That's because the old name was a not-so-clever play on my name that was later appropriated for a rather different collection of writing. I think that's worth resetting the Google credit counter to get away from.

    Oh and there have been a few upgrades…

    New Content

    All of my posts are back. Some content is a bit dated and I've tried to add clarifying notes where they were needed, but I was pleasantly surprised to see that much of it is still useful today. I believe my coverage of Character Encodings is what readers missed the most and it's fully restored.

    Read more…

  • 21

    MAY
    2012

    Decorators Verses the Mix-in

    It is a neat time to be involved in the Ruby community, if you ask me. A large portion of us are currently studying the techniques for doing good object oriented development. We are looking at the ideas that have come before and trying to decide the best ways to apply those ideas to our favorite language. This leads to blog posts, forum threads, and conference talks about what we are learning. No matter what, we all gain from explorations like this. Everybody wins as our collective knowledge grows. We all deserve gold stars.

    So far, there's one point pretty much everyone agrees on: composition should typically be preferred to inheritance. The trickier part of that discussion though is deciding what composition looks like in Ruby. Generally you see Rubyists comparing the merits of decorators and mix-ins. [Note: the comments correctly pointed out that this was a bad use of the word "composition" on my part, to describe mix-ins.] There's a very representative thread on the excellent Objects on Rails mailing list.

    Read more…