RubyLove

Functional Ruby, Code Beauty, and Ruby Internals

TDDing Pat Shaughnessy's Ask Don't Tell

Prefer The Declarative Over The Imperative

This article was spawned in response to a comment on Pat Shaughnessy's awesome article Use An Ask, Dont Tell Policy With Ruby asking about TDDing the example

TDDing Yeats

Take the following text (The Lake Isle Of Innisfree)

I will arise and go now, and go to Innisfree, And a small cabin build there, of clay and wattles made: Nine bean-rows will I have there, a hive for the honeybee, And live alone in the bee-loud glade.

And I shall have some peace there, for peace comes dropping slow, Dropping from the veils of the morning to where the cricket sings; There midnight's all a glimmer, and noon a purple glow, And evening full of the linnet's wings.

I will arise and go now, for always night and day I hear lake water lapping with low sounds by the shore; While I stand on the roadway, or on the pavements grey, I hear it in the deep heart's core.

We want a script to be run against this text and to match a word against it. If a match is made, that line, and all lines after it will be returned.

We already know what the code should end up looking like, we have the post. But we need to TDD it, so where do we start? To me the obvious entry point is the domain logic.

Reading a file is not domain logic. Matching a word against text and return a value is, so we will start with the lines_after test.

We will need some lines to test against, so lets load those into an array directly from the Yeats poem. We will also need our first test!

If the target word is not found anywhere in the poem, then we want to return an empty array.

require 'minitest/autorun'

describe "#lines_after_word(lines, target)" do
  let(:lines) { File.readlines(File.expand_path("../innisfree.txt", __FILE__)) }

  it "must return an empty array if no lines include the target word" do
    lines_after_word(lines, "hola").must_equal []
  end
end
Load the rest of the article

Applying Design Patterns To Ruby

Making our deck of cards more beautiful still

  • This is part 2 of a multi-part series. Read part 1 here.

Confident Ruby

If you do not already know who Avdi Grimm is then please, go check out his Confident Ruby when you have time. It is an AMAZING read. If you know about Confident Ruby already then you get to see some examples here.

Essential this style of coding uses liberal casting to keep nils and conditionals out of your code. It is also a style of Ruby that adheres to the "Tell, don't ask" principle. Because co-opting nils is evil, as is reaching into an object's state in order to decide what it should do.

Let's go back to our deck of cards. I put it into a repo for you this time so you can work along with me. Once that is forked, clone it down. You will find all the tests are there, just like I promised in part 1!

You can also compare that to the original gist to see where I started from if you aren't down to read part 1.

Step 1 - Change the Structs to an immutable object

Since we are going for a mostly functional approach here, I don't want the option to mutate these cards. To get closer to accomplishing that, we need to replace the structs that Deck is composed of, Card and Suite, with Value objects from Tim Crayford's library, Values.

These are pretty much like structs, however they are immutable. I will point out here that there is a bug in the gem version that doesn't seem to be in the github version. Because of that bug we will use the Class version instead of my prefered 'struct block to const' method.

Old
Rank = Struct.new(:rank, :value) do
  def to_s; rank; end
end
New
require 'values'

class Rank < Value.new(:rank, :value)
  def to_s
    rank.to_s.capitalize
  end
end

I made one more change here to be "Confident". I cast rank to a string. That removes any chance of getting a nil value! I may get an empty string, but I wont get a nil. Then for style consistency I capitalize the first letter and lowercase the rest.

Now onto the Card struct where do similar work:

Old
Card = Struct.new(:rank, :suit) do
  def to_s; "#{rank} of #{suit}"; end
end
New
require 'values'
require 'rank'

class Card < Value.new(:rank, :suit)
  def suit
    (@suit || 'naked').to_sym
  end

  def to_s
    "#{rank.to_s} of #{suit.to_s.capitalize}"
  end
end

Can you spot what I did here to make my code more confident?

In suit I et the value of @suit OR 'naked' in the case when @suit is nil, then again, for the sake of consistency in my formatting, I cast it to a symbol. We do something similar in to_s where I cast rank to a string, and I do for suit what I did for Rank#to_s.

We might get some ugly results if passed ugly data. But what it WONT do is barf all over you. It is also as the great Jim Weirich would say, "Polite Ruby".

The origin Deck itself requires no modification here for swapping out those Structs for Values. That is a bwnwfit of good design and the Single Responsibility principle. We needed to change some objects under the hood, yet we didnt have to change the object that uses them.

That is it for this post. I will be back very soon to explain why the the approach I took to Deck#build_deck and Deck#all_ranks is functional, and how it is superior to an typical imperative approach.

Stay tuned!

Load the rest of the article

A Faux-O Deck of Cards

Mixing Functional and OO styles FTW

A Functional OO Deck of Cards..

Let's build a deck of cards today using a hybrid approach, that is to say, lets use good Object Oriented design but keep our objects stateless and our functions idempotent.

I am going to skip the tests for brevity - the test 'noise' in non-testing articles is a bit much for this format. I however do have tests, and I encourage you to write tests!

We are going to need to describe a deck of cards using objects, so let's look for some logical boundaries and give them names. One way we can do this by describing what we want in a paragraph and a title. Let's do that now!

A _Deck_ of _Card_s is used to play many different types of games.

_Card_s have a _Rank_ and a _Suit_ and depending on the rules of the game,
these are used to score. Also, many games require a _shoe size_, which
specifies how many standard _Deck_s of _Card_s to include in the generated
_Deck_.

After I wrote that paragraph I underlined what I would call actors, which may or may not become objects or collections of objects. These are usually the recurring nouns.

Load the rest of the article

An Exercise in Refactoring in Ruby - Part 2

Using Extract Method Object to refactor large methods

I have previously been over the extraction pattern, Extract Method. Today we will explore it's big brother, Extract Method Object.

The Extract Method Object pattern is used to take a method or groups of methods from coupled, untestable code into code that adheres to the Single Responsibility Principle, or an object/ method/construct should have 1 and only 1 reason to change.

Let's jump right into some very scary, real, untestable (mostly) controller code:

...
  def update
    if (params[:user][:password].blank? && params[:user][:password_confirmation].blank?)
      params[:user].delete(:password)
      params[:user].delete(:password_confirmation)
    end

    if params[:user][:photo_attributes]
      Photos::Manipulation.update_resource_photo(current_user.photo || Photo, params[:user][:photo_attributes], current_user)
      current_user.photo.try(:reload)
    end

    if current_user.photo.nil? || current_user.photo.cropped?
      update! do |success, failure|
        @daily_snapshot = @user.daily_snapshots.new_to_old.first
        failure.html { render :basics }
        success.html {
          flash.notice = 'successfully updated'
          if @user.basics? || params[:next_screen] == 'accounts_user'
            sign_in(@user, :bypass => true) if (@user.valid_password?(params[:user][:password]) && params[:user][:password] == params[:user][:password_confirmation] && !@user.partner_editor?)
            redirect_to basics_user_path(@user) and return if @user.complete? && !@user.partner_editor?
            if @user.partner_editor?
              redirect_to user_path(@user.invited_by_id)
            else
              redirect_to accounts_user_path(@user)
            end
          elsif @user.interests? && params[:next_screen] == 'show_user'
            @user.complete unless request.xhr?
            redirect_to user_path(@user)
          else
            redirect_to interests_user_path(@user) and return if @user.complete? && params[:next_screen] == 'show_user'
            redirect_to basics_user_path(@user) and return if @user.complete? && params[:next_screen] == 'accounts_user'
            redirect_to user_path(@user)
          end
        }
      end
    else
      render :basics
    end
  end
...

Whew! That is one big ball of mud!

Load the rest of the article

A Deeper Look at Ruby's Enumerable

The most powerful part of ruby you don't use

Have you ever needed to load a VERY large file in ruby? No I don't mean your 500 line rails model. I mean a several gig binary or text file.

Try it. Watch your machine become unresponsive. Cry a little inside. Then reach for enumerable.

Ruby's Enumerable module gives you a way of iterating over collections in a lazy manner, loading only what you need, when you need it. But it gives us so much more than that.

Today I am going to walk you through a couple of highly useful methods from Enumerable that has come up in a few coding challenges I have done over the years.

each_cons, any?, all?, none?

I use these methods when I need to determine the 'distance or difference' in a set of numbers or objects. each_cons simply gives us a 'sliding' window of our list so we can compare multiple items in our list.

numbers = [1,3,5,8,10,54,99]
cards   = [5,3,4,6,2]

# get only the values where the distance is greater than 10
numbers.each_cons(2).select {|a,b| b-a>10 } #=> [[10, 54], [54, 99]]

# determine if the hand is a straight
cards.sort.each_cons(5).all? do |series| 
             (series.first..series.last).to_a == series
           end #=> true
Load the rest of the article

An Exercise in Refactoring in Ruby

Using extract method and idiomatic Ruby to refactor

Today I want to examine one of my favorite refactoring patterns, Extract Method.

  • When a method does too much or is too long? Extract method.
  • When you see a conditional with an if and an else. Extract method.
  • When you see a comment... EXTRACT METHOD!

Consider the following code:

def update
  if params[:credit_card]
    #process order
    response = @order.process(params)
    if response[:status] == "success"
      render :template => "orders/show"
    else
      render :json => response
    end
  else
    if params[:shipping_contact].size > 0  &&
params[:shipping_address].size > 0
      @order.create_shipping_contact(params[:shipping_contact],params[:shipping_address])
    end
    render :template => "orders/show"
  end
end
Load the rest of the article

Ruby Lambda Programming - Part 1

Crazy good fun with lambdas!

Ruby Lambda Programming (I just made that up) or MatzLISP (credit:Matz) is a very un-ruby looking style of ruby using pure higher order functions to get our work done. The functions are lazy, idempotent, functional, and single purpose. Well, they are if written correctly. But enough of wordy nonesense, how about an example?

Now wait just a minute, my friend. Before we jump to code we need a problem to solve!!

I present to you, a problem to solve!

For those who don't click links, here is the first part of the problem at hand:

  • take a list of natural numbers (1,2,3..10)
  • square each number and return the list of squares
  • sum that list of numbers and get 385

So essentially the equation for that looks like:

  • (1*1)+(2*2)+(3*3)..+(10*10) = 385

Ok, now we can have some code. Since this is just a single file ruby script, it might look a bit different from say, a rails file. We don't have bundler set up here, so I will need to call to gem and require to get minitest going. I will be using ruby 2.0 here out.

gem 'minitest'
require 'minitest/autorun'

describe "sum_squares" do
  it { assert_equal 385, sum_squares.(1..10) }
end
Load the rest of the article

Idiomatic Ruby 1

You probably aren't writing ruby..

Idiomatic Ruby 1

OK, so you are writing IN ruby, but you probably aren't writing ruby. You are writing c/basic in rubyish syntax. This is bad. Slap your hand bad. Makes Matz cry bad. You should be writing in idiomatic ruby.

So what does this idiomatic ruby I speak of look like?

What better way to present my case then by starting with some c/basic ruby?

def some_long_method_with_many_problems(user, ids)
  vals = []
  ids.each do |id|
    vals << user.returns_a_hash(id)
  end

  if vals.any?
    retval = do_something_with_hashes(vals)
  else
    retval = do_something_without
  end
  retval
end

And then refactor it into this idiomatic ruby we get much different looking code. Code that is clean and neat and terse. ruby code!

def some_better_method(user, ids)
  vals   = ids.map     {|id| user.returns_a_hash(id) }
  method = vals.any? ? [:do_something_with_hashes, vals] :
                       [:do_something_without]
  send(*method)
end
Load the rest of the article

Welcome to RubyLove

A new blog about Ruby and why we love her

Ruby is not just an OO language

It is much, much cooler than that

Take the following code.

# Functional coding in Ruby - better than chunky bacon
print_to_console   = ->(msg) { puts msg }
print_to_motd_file = ->(msg) { File.write("motd.txt", msg) }

# Display the "message of the day" via the selected printer
motd  = ->(printer) {
  msg = ["Hello World,\n",
        "  Sincerely,\n",
        "  thatrubylove"].join
  printer.(msg)
}

# Echo to the console
motd.(print_to_console)

# write to a file
motd.(print_to_motd_file)

Whoa! What is going on there? Actually it is very simple, functional ruby when you understand how ruby treats lambdas. Essentially we are holding off evaluation until called. We start off by creating a couple of macros which will be expanded when they are called, and within the context of where they were called.

Load the rest of the article