Tweetegy On the edge of chaos with Ruby, Rails, JavaScript and AngularJS.

| About | Search | Archive | Github | RSS |

Dissecting thesmallestrailsapp.com (Smallest Rails App: line 3)

In this post, I will carry on from where I left off in the previous post and continue my dissection of the smallest Rails app! This takes us onto line 3 of the code (since line 2 is empty!). Line 3 looks like this:

1 run TheSmallestRailsApp ||= Class.new(Rails::Application) {

This shows a call to Class.new which in Ruby means creating an anonymous class which inherits from the class passed into the new call.

Background for Class.new

The Class.new method signature is Class.new(super_class=Object) which means that you can specify the superclass by passing in the Class constant or if nothing is specified the default superclass will be Object.

One thing to note with this technique is that the class is unnamed or anonymous until such point that it is assigned to a constant. In the case of The Smallest Rails App the new class is assigned to the constant TheSmallestRailsApp.

One use for this would be to create a new class that inherits from another but does not have any body. A common example is when it’s necessary in a Ruby application to have a domain specific named exception available for rescue. For example:

1 SomeCustomIssue = Class.new(StandardError)

This way its possible to rescue SomeCustomIssue within the application. Using Class.new to define this custom Error class is far cleaner than using the more common class declaration syntax which would look like this:

1 class SomeCustomIssue < StandardError
2 end

Class.new can also take a block of code which will can be used to define methods (using class_eval) in the new class. For more information on where developers might use Class.new check out fun with class.new and when to class.new

The run command

Working backwards we see the "run" command at the start of the line. This is part of Rack and only works if executed on the command line using the rackup command. Usually the Ruby code for a Rack application is saved in a file called config.ru (especially in a Rails app) however this is not necessary and can be saved as a ruby file (with .rb extension) too.

Another intesting thing to note is that the run command comes from the Rack Handler Module. This means that the actual call to run could also be written as this:

1 Rack::Handler::Thin.run

I happen to have the Thin gem installed so this runs fine on my machine. If you don't have Thin installed then you will probably see the error "`require': cannot load such file -- thin". This is Rack evaluating the code and trying to require thin automatically. Just install the thin gem or use a different Rack::Handler. Of course, just simply call run and Rack will use whatever handler it finds on your machine automatically. For details on how Rack does this check out the Rack source code.

One error you might come across when trying to run this Rack application in your environment is "undefined method 'append' for ActionDispatch::Routing::RouteSet". In my case it was becasue the gemset that I was using was using an earlier version of Rails (3.0.x). Switching to another gemset with Rails 3.2.x fixed this issue.

Refactorings

In the Railscast, Ryan refactors this particular line to the following:

1 class TheSmallestRailsApp < Rails::Application
2   #code in the class are on other lines so ommited here
3 end
4 
5 run TheSmallestRailsApp

Note above that I have not included the body code of the class. The above code is essentially the same as line 3 of the Smallest Rails App except expanded to 3 lines. It demonstrates that a call to Class.new creates a class that inherits from the constant passed to it (in this case Rails::Application) and that it is assigned to the constant TheSmallestRailsApp which is then run as a Rack app.

Conclusion

In line 3 we learned about Class.new, anonymous classes a little about rack applications. Next post will be about the next line of code!