Matthew Hinton

Just where I spout off on whatever I feel like

Tag: ruby

A Great Ruby Book

I recently finished reading a great book Practical Object-Oriented Design in Ruby by Sandi Metz also referred to as POODR. This is one of the best software design books I have read. I usually skim a technical book because they are usually so dry or basic that I find myself not getting much out of them and I will drop them half way through. POODR however uses a great iterative method of illustrating it’s points. This kept me engaged and thinking about what I was reading.

Sandi starts with a naive implementation of a solution to a design problem and then shows the issues that arise from that solution. She then iterates the solution several more times until she has arrived at an elegant solution that will deal with change well. Sandi stresses that a good design is one that deals with change well.

POODR taught me how to approach design problems in a more Ruby way. I really enjoyed POODR and I feel like I got a lot out of it. I have already used the lessons I learned from it several times. I have also been able to illustrate to the other developers on my team why doing the things I have learned are a better way to approach a problem than what had been done previously. I personally and through me my team have benefited from Sandy’s excellent work. I highly recommend Practical Object-Oriented Design in Ruby for anyone interested in working with Ruby. I think it would be a great second Ruby book for anyone after reading a book on the Ruby language like Programming Ruby.

Ruby Sort a Subset of Array Elements

Here is a little trick I came up with for sorting a subset of array elements in Ruby.

I needed to sort a subset of elements in an array while leaving the other elements in the positions they occupied.

The algorithm I used was to create a new array with just the items I want to sort. Sort the new array’s elements. Then you have the original array that contains all the elements and a second sorted array with just the items you are interested in. The original array and the sorted array both contain the same subset of items then you want sorted. So go through the original array and whenever you find one of the items you wanted to sort replace it with the next item from the sorted array.

Ruby array subset sort

 all_elements = [1, 'b', 2, 'a']
    subset = all_elements.select {|i| String === i}
    subset.sort!
    all_elements.map do |i|
        if i.kind_of?(String)
            subset.shift
        else
            i
        end
    end

Stubbing out a method implementation in RSpec

I needed to have a method call return different results depending on the argument passed to it in RSpec today so I am putting a write up here on how this is done.

When stubbing a method in RSpec you can pass a block to it to determine the return value based on the input to the method.

I needed this because I needed to test the result of the nth invocation of the method.

Rspec implementation injection

 Model.stub(:method_name) do |input|
        false if input == "asdf"
        false if input == "asdf2000"
        false if input == "asdf1000"
        false if input == "asdf1001"
        false if input == "asdf1002"
        false if input == "asdf1003"
        true  if input == "asdf1004"
    end
    result = Model.method_name(@arg1, @arg2, @arg3)
    result.should == "asdf1004"

Ruby Metaprogramming Goodness

Ruby allows you to do nice things like take an object serialize it to json send it somewhere like across the wire and reconstitute it.

Reconstitute the object

klass = message.keys[0].camelize.constantize

New instance of the klass

event = klass.new

Attributes of the class

attributes = event.attributes

Attributes and values from the message

attribute_values = message[message.keys[0]]

Copy the attribute values from the message into the object

event.attributes.each {|attr| event.send("#{attr[0]}=", attribute_values["#{attr[0]}"])}

Avoid Overloading Language Operators

I needed to do some date arithmetic in Ruby today and I wasn’t easily finding a way to do it. I kept looking for an easily discoverable way to add values to parts of the date. I finally found what I was looking for on stackoverflow. The Ruby Date class overrides the +/-/<</>> operators to do date arithmetic. This doesn’t seem like the most intuitive way to do it to me. I would much prefer there were methods on the Date class such as addday, addmonth, add_year, or an advance method that took a hash of date part options like Date.now.advance({:day => 3}).

© 2017 Matthew Hinton

Theme by Anders NorenUp ↑