thoughts.inject(world)

Dec 26

Spraying for Weeds

Solo backpack sprayer

What? Really?

Yes, really. It’s the day after Christmas and I spent most of the afternoon spraying for weeds, blowing leaves, and doing other assorted yard cleanup tasks. That probably seems a little bizarre to those of you who get to enjoy the kind of “White Christmas” that is only myth to the Upstate of South Carolina but where a winter day resembles some autumn mornings in New England it’s okay. Besides, it has its advantages.

First, only hours removed from Christmas I can already tell that I need the exercise. I enjoy yard work for that simple fact. There’s a pretty obvious, and some would say annual, resolution coming here for the New Year but that’s a story for another day.

Second, and more importantly, the time spent doing yard work is great time to think. Lawn mowers, blowers, and their kin are great white noise generators that quickly fade into the background. At the same time, the tools of the trade also create some distance for uninterrupted thought.

Today’s tour of the yard helped me finally knock out a task that has long been calling me: spraying for weeds. Nearly half of our yard is consumed by mulch beds that seem to be very inviting to weeds. With the busy schedule we had this fall the weeds gladly accepted the invitation and felt right at home.

Killing weeds in December

To combat the weeds I mixed some concentrated weed killer into my backpack sprayer and set out to the backyard. The privacy fence beside the kids’ fort fell quickly as did the side yard that’s primarily green space. I felt a little cheated when I got to the front yard. There was a strong stand of weeds in the bed that we share with one of our neighbors. I sprayed those weeds and followed them into the neighbors yard, cleaning up a bit of that as well. I completed the circuit by knocking out the edge of the yard along the drive. That was the part that bothered us the most — we see it as we go in and out of the house.

The advantage of taking care of weeds at this time of year is pretty simple: if it’s green it’s a weed. Our bermuda lawn is dormant for the winter so we can spray weeds there without worrying about killing the grass. The flower beds and gardens are similarly slumbering for the winter so those can also be cleaned up. There is no “pressure” to keep up all the yard. I can just concentrate on the weeds.

Spraying for Weeds = TDD

Naturally (pun intended), spraying for weeds led my thoughts to Test Driven Development (TDD). Spraying for weeds in December is similar to TDD in that I get to concentrate on how the lawn should look. I can define the outline of the bed without worrying about the side effects of the weed killer (it has a tendency to hurt the runners in bermuda grass and leave odd looking yellow streaks in the lawn). Cleaning up the beds during December isolates me from the “pressure” of caring for the whole active yard. In a similar way TDD allows me to concentrate on a particular piece of the overall puzzle without the “pressure” of working a quick fix for an effected customer.

Staying focused

The side trip into my neighbors’ yard also has some implications on TDD. On projects that involve more than one developer — that is most software of consequence — you’ll often find yourself “sidetracked” into your neighbor’s code while tracing out functionality. In these situations it’s often best to touch only that part of the code that directly impacts your own. For my own part I sprayed only that part of the bed that touched my yard and had weeds. Why? Because I only had a certain amount of weed killer and I needed to make sure that I used it to focus on my yard first. In truth I finished up my yard with some weed killer to spare so I returned to my neighbors adjoining bed and sprayed as far as the weed killer would take me. In a similar way, development time is limited. By concentrating on a particular part of the code base and tracing the code in question into other parts of the code base but only as far as they impact the code in question you keep one primary thought in mind and typically solve it more quickly. You can always return to “the scene of the crime” and clean it up with tests in the future!

But Weeds and Bugs Still Follow

Another thought occurred to me about TDD while spraying those weeds: next spring other weeds will eventually grow. Some have criticized the TDD movement over assertions that it’s ineffective because it does not prevent bugs. That charge is an over-reaction to blind faith assertions of TDDers that TDD produces bug-free code. In reality neither is true.

Software represents our best understanding of the problem and its solution at a point in time. In TDD this knowledge is captured both in the code used by the user and the test cases that outline the requirements. As the days pass, nuances of the problem will reveal themselves and unconsidered edge cases will arise. In some cases this is reported as a “bug” — and from the user’s perspective it probably is because the software as designed did not meet their expectations. This is a natural cycle in software development. When applied correctly, TDD accounts for the new “weeds” in the code base in the same way as the original “weeds”. New tests are created to describe the additional information about the problem domain and new methods are added to solve it. So with TDD we do not simply assume that the weeds will never arise; we apply the same method and deal with the weeds if and when they do arise.

From our neighbors’ yard, of course.

Dec 17

When is it time to refactor?
It’s time to refactor legacy code when… you see a rainbow and not the code.

When is it time to refactor?

It’s time to refactor legacy code when… you see a rainbow and not the code.

A person can only be a novelty once, and only briefly, and charm, like any commodity, when used uneconomically becomes a wasting asset.

- George Will, 17-Dec-2009

Dec 04

[video]

Nov 16

I am the Keymaster, are you the Gatekeeper?

Rick Moranis in Ghostbusters

Several weeks ago I started writing an authorization gem on the way home from a weeks’ vacation. The problem with the set of gems and plugins that I’d used in the past were several. One gem was much too tightly coupled to an authentication gem that I no longer used. Others required too much wiring. So, off I went to create the next great gem. At least until I got home and ran into a stray question in a ruby forum about the DeclarativeAuthorization gem.

DeclarativeAuthorization is the gem that I wished I’d written for a number of reasons. First, DeclarativeAuthorization is almost entirely self-contained from the rest of your application. It’s only requirement is that your user/account model support a collection of role_names. How you support that collection is entirely up to you. That’s the kind of separation that I really wanted and that ultimately had triggered my ideas for writing a gem in the first place.

DeclarativeAuthorization uses a ruby script to define roles and to assign privileges to those roles. The approach is simple and clean… even when the rules for roles get murky. There are two big advantages to this. One is that the rules do not depend on any “Rails magic” or golden values in your database. The other is that the roles and privileges can grow with your project regardless of the eventual complexity.

Composing Privileges

Out of the box DeclarativeAuthorization has a simple set of privilges for CRUD… conveniently named Create, Read, Update, and Delete. The privileges are declared as follows.


privileges do
  privilege :manage, :includes => [:create, :read, :update, :delete]
  privilege :read, :includes => [:index, :show]
  privilege :create, :includes => :new
  privilege :update, :includes => :edit
  privilege :delete, :includes => :destroy
end

What’s been really well thought out here is how privileges should be composed together. For example, it seems fairly obvious at the UI level that in order to be able to ‘update’ something you must first be able to ‘edit’ it (at least in the Rails view of REST). Similarly, DeclarativeAuth sensibly defines ‘read’ as ‘show’ and ‘index’.

But what if you wanted to go a level higher? For example, what if you have an admin area and you know that only admins should be able to perform any CRUD? Won’t it get annoying repeating tests for each aspect of CRUD? Nope. Because you can compose the privileges. That’s the essence of the first line of the block. In that line we have a “manage” privilege that is defined to be the same as granting each individual C/R/U/D privilege.

Roles Compose, Too!

DeclarativeAuth also supports composing roles as well.


authorization do
  role :guest do
    has_permission_on :conferences, :to => :read do
      if_attribute :published => true
    end
    has_permission_on :talks, :to => :read do
      if_permitted_to :read, :conference
    end
    has_permission_on :users, :to => :create
    has_permission_on :authorization_rules, :to => :read
    has_permission_on :authorization_usages, :to => :read
  end
  
  role :user do
    includes :guest
    has_permission_on :conference_attendees, :to => :create, :join_by => :and do
      if_attribute :user => is {user}
      if_permitted_to :read, :conference
    end
    has_permission_on :conference_attendees, :to => :delete do
      if_attribute :user => is {user}
    end
    has_permission_on :talk_attendees, :to => :create do
      if_attribute :talk => { :conference => { :attendees => contains {user} }},
          :user => is {user}
    end
    has_permission_on :talk_attendees, :to => :delete do
      if_attribute :user => is {user}
    end
  end

  ...
end

Obviously there’s a *lot* going on in that code snippet. The point here is found in the first line of the block for ‘role :user do’ — ‘include :guest’. Simply put, the user gets to do everything that a guest can do plus what’s defined in the rest of the block. That makes for a very powerful and concise way to keep track of roles and privileges.

Without getting into the details too much, the other thing to note in the definition of the :user role is the if_attribute calls. if_attribute allows the role definition to move beyond global scope for the class and validate privileges on an instance by instance basis. The if_attribute calls in the :user definition essentially say “if the current user is the user associated with the instance (the one that created it) then the user can…”.

Integration across the Rails MVC stack

With the ability to set privileges based on attributes of a particular instance you may be thinking, “Wow, I could use that to secure data at the instance level…” You’d be right. And, of course, DeclarativeAuth already does that.

DeclarativeAuth has a simple API that allows you to specify privileges in the models to secure access at the (data) class level in addition to the broader access control at the controller level. There are even nice helpers available in the views to show/hide UI based on the privileges of the current user.

ConferenceAttendee data class


class ConferenceAttendee < ActiveRecord::Base
  using_access_control
  
  belongs_to :user
  belongs_to :conference
  validates_presence_of :user, :conference
  validates_associated :user, :conference
end

ConferencesController#index


def index
    # Only show conferences that the current user may read:
    @conferences = Conference.with_permissions_to(:read)
 
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @conferences }
    end
  end

Note: All the code snippets presented here come from the sample app for DeclarativeAuthorization

Nov 06

Thinking Functionally in Ruby -

Tom Stuart introduces Functional Programming ideas to Ruby developers at a London Ruby User group meeting.  Great intro to FP with a reference to the most FP-like module in Ruby: Enumerable (and my personal fav Enumerable#inject).  Even if FP is not your thing it’s worth watching the video from around the 35 minute mark on to see the Ruby examples.

Oct 24

[video]

Oct 22

Becoming a fan of MacVim
A few weeks ago some of my colleagues through down the gauntlet: learn vim or give up lead dog status.  Not wanting to shrink from a challenge I decided to start playing with it and got hooked.
The screenshot above shows one scenario in which (Mac)Vim really shines.  I really like the simplicity of setting up a split screen in vim.  When you&#8217;re trying to stick to a red-green-refactor cycle for developing business logic this layout is great.  Here I&#8217;ve got the spec on the left and the model on the right.  By sitting them side-by-side like this I don&#8217;t get quite as tempted to cheat the process, adding a bunch of code and then adding tests that pass, as I did in the singular view that I typically saw in most IDEs.
The other aspect of the screenshot is down at the bottom.  A few keystrokes in Vim and you can execute command line stuff from within Vim.  So not only can I view the spec and the model it&#8217;s describing side-by-side but I can also run the test in place as well.  And in the event of a failure &#8212; which I should have if I&#8217;m following the red-green-refactor approach properly &#8212; then I can see the failure, the spec that failed, and the class that failed.  Pretty powerful.
The comment that really got me to try Vim was that it&#8217;s everywhere.  Well, okay, not everywhere but it&#8217;s in all the environments that I need to use for development.  The MacVim release on my MBP is nice and stable.  Vim is, of course, alive and kicking on the Linux distros I&#8217;ve used for staging and production servers as well.  The rational was pretty simple: learn one tool and carry it with you everywhere.  That rational works for me.
Don&#8217;t miss Tim Pope&#8217;s Rails support
If you&#8217;re going to give MacVim a shot, make sure that you strongly look into the extensions that Tim Pope has constructed.  The vim-rails plugin is great for Rails developers.  For example, with vim-rails I can key &#8220;Rview accounts/show&#8221; and it opens up the Rails view for Accounts#show.  Tim&#8217;s also got plugins for haml and cucumber if you&#8217;re working with those, and recently added a wrapper for git.  Great stuff (not all of which I&#8217;ve been able to toy with but all worth a looksee.
So, what do I give up?
What you lose with Vim are some of the niceties of a traditional IDE.  Since I&#8217;ve only been using MacVim for a short while I have not found a project viewer like you&#8217;d have in TextMate and most IDEs.  Refactoring is a manual process&#8230; but in most Ruby IDEs that still true so you&#8217;re not sacrificing much if you can handle grep (from within Vim, of course!).

Becoming a fan of MacVim

A few weeks ago some of my colleagues through down the gauntlet: learn vim or give up lead dog status. Not wanting to shrink from a challenge I decided to start playing with it and got hooked.

The screenshot above shows one scenario in which (Mac)Vim really shines. I really like the simplicity of setting up a split screen in vim. When you’re trying to stick to a red-green-refactor cycle for developing business logic this layout is great. Here I’ve got the spec on the left and the model on the right. By sitting them side-by-side like this I don’t get quite as tempted to cheat the process, adding a bunch of code and then adding tests that pass, as I did in the singular view that I typically saw in most IDEs.

The other aspect of the screenshot is down at the bottom. A few keystrokes in Vim and you can execute command line stuff from within Vim. So not only can I view the spec and the model it’s describing side-by-side but I can also run the test in place as well. And in the event of a failure — which I should have if I’m following the red-green-refactor approach properly — then I can see the failure, the spec that failed, and the class that failed. Pretty powerful.

The comment that really got me to try Vim was that it’s everywhere. Well, okay, not everywhere but it’s in all the environments that I need to use for development. The MacVim release on my MBP is nice and stable. Vim is, of course, alive and kicking on the Linux distros I’ve used for staging and production servers as well. The rational was pretty simple: learn one tool and carry it with you everywhere. That rational works for me.

Don’t miss Tim Pope’s Rails support

If you’re going to give MacVim a shot, make sure that you strongly look into the extensions that Tim Pope has constructed. The vim-rails plugin is great for Rails developers. For example, with vim-rails I can key “Rview accounts/show” and it opens up the Rails view for Accounts#show. Tim’s also got plugins for haml and cucumber if you’re working with those, and recently added a wrapper for git. Great stuff (not all of which I’ve been able to toy with but all worth a looksee.

So, what do I give up?

What you lose with Vim are some of the niceties of a traditional IDE. Since I’ve only been using MacVim for a short while I have not found a project viewer like you’d have in TextMate and most IDEs. Refactoring is a manual process… but in most Ruby IDEs that still true so you’re not sacrificing much if you can handle grep (from within Vim, of course!).

Best. Drink. Ever.

Best. Drink. Ever.

Oct 21

What’s in a name? Inject-ing your code

thoughts.inject(world)?

If you’re new to Ruby you may not realize that the title to the blog is an ode to one of my favorite Ruby idioms: inject. In a nutshell, inject is a customizable accumulator that Ruby mixes into collections through the Enumerable module (e.g., arrays and hashes).

Anatomy of an inject-ion

inject essentially has four parts: a collection to be iterated, a seed value, an accumulator, and a block used to ‘accumulate’ the members of the collection. In practice it looks something like this:


collection.inject( seed_value ) do |accumulated_value, collection_member|
  accumulated_value.modify_by collection_member
end

Given that structure, here’s what happens

  1. accumulated_value is initialized with seed_value.
  2. accumulated_value and the first (second, third, …) value of the collection is passed to the block.
  3. The result of executing the block — the value returned by the last statement — is assigned to accumulated_value.
  4. Repeat the previous two steps for every element of the collection.
  5. Return the last value assigned to accumulated_value.

A simple example

The simplest, and probably canonical example, of using inject is to sum the values of an array.


[1, 2, 3, 4, 5].inject( 0 ) do | total, value|
  total + value
end

Just to be thoroughly pedantic, let’s step through what’s going on here based on the explanation above. First, total is assigned the seed value of 0. Next, 0 and the first value of the array (1) is passed to the block and the block evaluates total + value (0 + 1) and assigns it to total. The next iteration passes that total (1) and the next value (2), performs the addition, and assigns 2+1=3 to total. And so on.

Now, if you’re using Ruby to build a database-backed application this might seem to be a bit of a waste. You can and should delegate simple sums like this to the database and avoid the cost of returning the values, instantiating classes, and then reading the attributes you want to sum. Databases live for that. Let them.

A more practical example

In one app that I support we were discussing how to bill customers. Stunning as it may be, that was a reasonably important issue for us so we wanted to get it right. The application primarily provides member management support and billing is tied to the population of members. The catch was that, at the current moment, both the member and the membership could be made inactive. I’m sure that there’s a sql guy out there who’s already got nested selects in mind but our app need only bill one time per month so we can afford to be a little less than optimal here. Inject to the rescue.


customer.memberships.inject(0) do |total, membership|
  membership.expired? ? total : total + membership.members.active.count
end

So, what’s going on? It’s really not that much more complicated than the sum example above. As before we initialize the count with 0. Next, we check each membership. If the membership has expired then we just return the previously calculated total. If not, we add the number of active members on the membership to the previously calculated total.

But wait, there’s more!

There are two great things about inject that should not be overlooked. First, the accumulator can accumulate in any way you want. That means you can use it to transform data as well. For example, we could test to see how random random really is by checking to see how well it distributes numbers by using inject.


numbers = []
1000.times{ numbers.push rand(4) }
numbers.inject( Hash.new(0) ){|frequencies, num| frequencies.merge num => frequencies[num]+1}
=> {0=>254, 1=>249, 2=>248, 3=>249}

Furthermore, since inject is a method that gets mixed in from the Enumerable module that means you can use it far more widely than just arrays. Hashes, strings, ranges… you name it. Anything that uses Enumerable can take advantage of inject. Taking a variation on the number frequency above, what about finding the average length of a ‘line’ in a string?


str = "The quick\nbrown fox jumped\nover the lazy\ndog."
str.inject( Hash.new(0) ) do |lengths, line| 
  len = line.split(/\s+/).size
  lengths.merge len=>lengths[len]+1
end

=> {1=>1, 2=>1, 3=>2}