Building Classes and Modules Programmatically

When I first started to get into higher-level Ruby, one of the most exciting finds was why the lucky stiff’s tiny web framework, Camping. This little package was packed with all sorts of wild techniques I had never seen before, including a way to write controllers to handle URL routing that just seemed out of this world:

module Camping::Controllers

  class Edit < R '/edit/(\d+)'
     def get(id)
       # ...
     end
  end

end

It didn’t even occur to me that such things could be syntactically possible in Ruby, but upon seeing how it worked, it all seemed to make sense. We’re not going to look at the real implementation here, but I can’t resist pulling back the curtain just a little so that you can see the basic mechanics of how something like this might work.

The key secret here is that R is actually just a method, Camping::Controllers::R(). This method happens to return a class, so that means you can inherit from it. Obviously, there are a few more tricks involved, as the class you inherit from would need to track its children, but we’ll get to those topics later.

For now, let’s start with a simple example of how parameterized subclassing might work, and then move on to more examples of working with anonymous classes and modules in general.

First, we need a method that returns some classes. We’ll call it Mystery():

 def Mystery(secret) if secret == "chunky bacon" Class.new do def message "You rule!" end end else Class.new do def message "Don't make me cry" end ...

Get Ruby Best Practices now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.