Brendon Murphy writes here.

See also the archive & miscellaneous.

Two Support Objects You May Have Missed

If you spend time daily in a large ruby project (such as a Rails app) that has ActiveSupport pulled in, you are likely relying on its string, time, hash, and other extensions. I’ve found two objects it provides prove useful, and having found them lesser known amongst my coding friends, figured they are worth sharing.

The first useful tidbit is the ActiveSupport::StringInquirer class. It’s a simple method missing call that lets you do prettier equality tests on strings. If you’ve ever done a Rails.env.development? check, it uses this implementation. Let’s go to the code:

Rails.env.development? # => true
Rails.env              # => "development"
Rails.env.class        # => ActiveSupport::StringInquirer

si = ActiveSupport::StringInquirer.new("foo")
si.foo? # => true
si.bar? # => false

I think this is great for two reasons. First, it’s a more expressive use of code, and secondly, it implies less coupling to a string outside of an object. Let’s take a simple example: a role for a User object. Imagine you start simple, where role is just a string. Now let’s say we’re using CanCan to add simple authorization to our app, with an ability class that looks like this:

class Ability
  include CanCan::Ability

  def initialize(user)
    user = user || User.new

    if user.role == "admin"
      can :manage, :all
    else
      can :read, :all
    end
  end
end

Note we’re doing an #== for comparison on that role. This is a bit ugly and not as expressive as I’d like. Let’s get rid of ugly with the help of the StringInquirer.

class User < ActiveRecord::Base
  def role
    role = read_attribute(:role).to_s
    ActiveSupport::StringInquirer.new(role)
  end
end

class Ability
  include CanCan::Ability

  def initialize(user)
    @user = user || User.new

    if role.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end

  private

  def role
    @user.role
  end
end

I’ve redefined User#role to wrap the attribute in a StringInquirer, and updated the Ability class to call the role with the predicate #admin? method. Our end behavior for ability checking is the same, but I think we’ve got more readable code. There’s another win on this: we’ve decoupled from treating our role like a string which can pay out nicely in the future. Imagine for instance the day arrives when a user no longer has one role, but many. A simple user may be able to function as both a forum moderator or a comment moderator. You can shift to supporting many roles per user with a bitmask method and leave your external calls untouched. A simple application of define_method or method_missing on your role attribute wrapper is all you need to keep rolling. Now, you could also define #== on your role object for such string comparisons, but comparing to a string reads more like the caller knows too much of an implementation detail. I haven’t touched on the User#role= setter here; you may need some sanitizing and cleanup on it if you were assigning it the results from the getter method anywhere (and, ahem, possibly breaking encapsulation with your own string assignments, too). I’ll leave that as an exercise for the reader.

Our second friend is the ActiveSupport::SecureRandom interface. Actually, saying this is from ActiveSupport is a little misleading. If you are working on an older Rails 2 project, you’ll probably be using this by way of ActiveSupport. However for modern and future use, this is deprecated and delegated to Ruby 1.9.x stdlib’s SecureRandom. SecureRandom is great for generating random character strings on the fly that are useful as API keys, temporary passwords, tokens, etc. It’s simple to use, and can replace those naive calls to rand() you’ve been making for generating random strings. Don’t reinvent the wheel! I’ll leave you with a few examples:

SecureRandom.hex    # => ace59c788b498fadcaa88216e45cf800
SecureRandom.base64 # => iJKR2NQ8Jk1wBdp0nU/fhA==

# Optionally pass 5 for 5 hex pairs
SecureRandom.hex(5) # => a5f8bf212f

Oct 16, 2011

/2011/10/16/two-support-objects-you-may-have-missed.html comments

Spec your codebase, not just your code

Many rubyists are familiar with using Test::Unit, RSpec, or MiniTest for specifying the behavior of their application code. Over the past year, I’ve discovered a novel and less conventional use of testing tools I like to call “specifying the codebase”. Let me show you what I mean.

If you’ve ever worked on a sizeable Rails project, you’ve probably experienced some codebase quirks at some point. For example, I’ve got an application that had issues when the Liquid Templating engine was loaded as a gem. The fix was to include a specific version as a plugin. While it’s usually best to get to the root of the problem, sometimes it’s not feasible or expedient and such measures must suffice. Once Liquid was included as a gem, we noticed some failing tests, and then pieced together that, oops, Liquid had been reconfigured as a gem. A code review may have caught this, or perhaps not, since it’s a little quirky. Now the second time we made the mistake, it dawned on me, write a spec to send up a red flag and make it easier to spot the immediate problem when tests fail in the future:

describe "The codebase" do
  it "doesn't load the liquid gem" do
    Gem.loaded_specs.any? {|s| s.first == "liquid"}.should be_false
  end
end

It’s pretty easy to make the mistake of not properly compressing or optimizing assets, especially images, in your app’s public directory. Code review or possibly even your vcs can help prevent such problems, but you can also let your specifications alert you to the problem:

it "/public directory includes files less than 1MB" do
  files = `find #{File.join Rails.root, "public"} -type f -size +1M`
  files.split(/\n/).should == []
end

The pattern emerging here is pretty simple: if you or your teammates make any repeat mistakes with your codebase, write a spec to prevent further repeats. By all means, make sure to communicate and talk out application guidelines, yet, nothing says “hey, over here!” like a failing test.

The applications here are pretty endless. Maybe you’ve got a Sinatra app on Heroku where you precompile dynamic stylesheets, and have made the mistake of checking in a busted css one too many times; there’s a spec for that! Or perhaps you’ve got an overzealous teammate adding or removing crazy things from git file index. First, do better code review and, secondly, there’s a spec for that:

it "leaves config/database.yml out of the repository" do
  git = Git.open(Rails.root)
  git.ls_files("config/database.yml").should be_empty
end

Finally, there’s some important safety notes for techniques like this. First, you may find yourself using system commands like find or grep. If you’re confident you’ve got a fairly consistent environment your application is developed and run on (i.e. *nix boxes) this is probably OK. However, don’t trickle this practice over towards reusable code, like gems you write and share with the world. It’s not kind to Windows users out there. Secondly, tests like this are often going to integrate with a real filesystem, so for goodness sake stick to read only operations. Don’t touch, rm, cp, or mv files about. If you find yourself wanting to perform destructive operation, the rakefiles are that-a-way. And again, don’t share this behavior with your application or gem code, but rather, use gems like FakeFS for testing in isolation of the filesystem.

Oct 01, 2011

/2011/10/01/spec-your-codebase%2C-not-just-your-code.html comments

NotNot Alternative

There’s a common ruby convention out there, I call it NotNot. You’ll find it often in predicate methods, and it looks like it sounds, ‘!!’. I suppose you could call it “Bang Bang”, or perhaps it has a real name I’m not aware of.

I don’t like NotNot, primarily I think because in my head it seems like the dreaded English grammar double negative. In other words, it’s just weird.

The point of the NotNot is for your classes to return true/false, rather than just truthy/falsy. Let’s start with a simple example predicate:

What? That looks kind of strange, however, it will pass conditional tests, since ruby treats the values nil and false both as falsy values, while other values as truthy. But again, the returns look weird. Enter the NotNot:

Hey, those returns looks better, I see we’re getting back real true/false which is really what we want. But that NotNot looks weird. Think about it in your head, what’s the value of not not false…uh.

Say hello to the TrueClass#& method. The TrueClass RDoc states that the & method “Returns false if obj is nil or false, true otherwise.”

You’ll note we’re still getting back true/false. The method is less terse than the NotNot, but I think slightly a better match intuitively.

In the end, it really boils down to style and readability. If you code Ruby, while it’s important to know the NotNot, I’d advise something your brain doesn’t have to double unroll.

Hat tip to my friend Bill for taking me straight from example 1 to 3 when I started in Ruby.

Jul 27, 2011

/programming,/ruby/2011/07/27/notnot-alternative.html comments

Onward to Jekyll

In the grand tradition of getting bored with blogging software, without actually taking the time to blog, I’ve transitioned software yet again. This time I selected Jekyll to try. I discovered that in the past I’ve had a habit of writing blog posts in TextMate or Vim, and then pasting them into whatever blog software I was using at the time. That’s silly. Now I can just edit in my editor of choice, have full syntax aware access to template and CSS documents without dealing with a nasty web interface, and have greater flexibility for throwing different pages up on the site. With blog software, it’s often like pulling teeth when you want those pages that are more CMS than blog. Not so with Jekyll. It’s a template system that simply builds a static site out of layout and markup files (I’m using textile). When you want that one-off page, all you have to do is drop it in. There’s no requirement that it play nice with the rest of your site, it could truly be a one-off if you so desired.

Anyway, if you want some fun and simple software to test-drive, I’d recommend it. Not that it’ll get me to post any more. Or perhaps, it will.

Sep 08, 2010

/2010/09/08/onward-to-jekyll.html comments

Metaprogramming in Ruby: Part 1

I joked with a co-worker the other day that, sometimes I think I’m better at Ruby metaprogramming that straight ahead programming. This is a serious exaggeration, and I don’t count myself as an expert at either. However, it dawned on me that, I have a few friends that aren’t as exposed to metaprogramming concepts in Ruby, so, what better topic to share about. Hopefully in the process, you’ll learn something new, and, I’ll become better at explaining Ruby concepts and sharing code.

Before I dive in with some introductory examples, a quick definition of metaprogramming is in order. To quote Wikipedia, “Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime”. If you use Rails (and, I know you do), metaprogramming enables things you already do on a daily basis, such as dynamic find_by methods in ActiveRecord, or plugins that dynamically get a class to include them (acts_as_list, acts_as_tree, etc).

In this writeup, I’ll start with two extremely basic metaprogramming concepts. In fact, these might not even be considered true Ruby metaprogramming, but, I wanted to start with some simple ideas which you may not have been exposed to in Ruby 101.

The first concept to get down in Ruby is that, classes are objects like anything else. In Ruby, this means you can open the class and modify it on the fly. The practice is affectionately called monkey patching or duck punching. Let’s look at a simple example:

You can see above, we’ve created a Foo class with a public instance method, bar. Calling foo.bar, we’ll get the output we expect, “bar!”. Next, we reopen the Foo class, and add a new public instance method, foobar. Had we tried to use Foo#foobar before this, we’d get a NoMethodError exception, as expected. However, having reopened and modified the class, we can call our new method.

The other demonstration I’d like to show is one way you can define methods on the fly. This example is abstract and doesn’t represent a recommended use, it’s simply to prove the point.

Running this simple example, the first call to foo_two.bar will output “bar”. However, once we call foo.cap_bar, the public instance method bar is changed. Running it a second time will output “BAR!!!”. A more common, rubyish way of defining methods at run time in Ruby is the use of define_method, which I’ll cover in a future post.

An important concept to keep in mind here is that, you aren’t modifying behavior solely on the foo or foo_two instances. Instead, you are changing the behavior of any open instance of the Foo or FooTwo classes. So in our FooTwo example, if you were to create a foo_too instance, calling foo_too.bar would run through the dynamically created method as well and output “BAR!!!”. In future postings, we’ll see a different approach of opening instances and defining methods specific to that instance.

Hopefully this has whet your appetite a little, and, in the future, we can run through some more exciting examples of the metaprogramming facilities Ruby has to offer.

Oct 30, 2009

/2009/10/30/metaprogramming-in-ruby-part-1.html comments