A handy ruby trick: Class.new

by Ben Orenstein

Today I learned that you can pass a block to Class.new, like so:

klass = Class.new do
  def self.speak
    "hi!"
  end
end

>> klass.speak
=> "hi!

This is a handy for creating one-off classes; the kind you’ll throw away quickly.

It’s likely that you’d do this during tests. Here’s a test in active_support that uses this technique:

class ClassAttributeAccessorTest < Test::Unit::TestCase
  def setup
    @class = Class.new do
      cattr_accessor :foo
      cattr_accessor :bar,  :instance_writer => false
      cattr_reader   :shaq, :instance_reader => false
    end

    # Now grab an instance of our new class
    @object = @class.new
  end
 
  # Elided: tests that make sure the cattr_accessor method behaves

end

Another thing I picked up at the same time: you can pass a constant to Class.new and it will set that as the superclass:

>> klass = Class.new(String)
=> #<Class:0x105604658>
>> klass.superclass
=> String

Here’s another test from Rails. This one makes use of both tricks I just showed you:

  test "configuration is crystalizeable" do
    parent = Class.new { include ActiveSupport::Configurable }
    child  = Class.new(parent)

    # ...
  end