Friday, January 22nd, 2010
Ruby is one of the most versatile object oriented programming languages, which was designed explicitly to have a human focus, as compared to the machine focus of many other languages. Developed in the mid-90’s, initially in Japan and then elsewhere, Ruby is based on the “principle of least surprise” (POLS) which states that when two elements of an interface conflict, or are ambiguous, the behavior should be the one that will be least surprising to a human user or programmer. In simple terms that the most obvious behavior is the one that will result. And this is perhaps what gives Ruby its power and in turn has caused Ruby to become one of the most widely used programming languages for the web. There are of course many other useful features in Ruby, including but not limited to Dynamic Typing, Duck Typing, Automatic Garbage Collection, First Class Continuations, an Interactive Ruby Shell, variable scope at four different levels (global, class, instance, local), facilities to support metaprogramming and a standard set of object oriented features (inheritance, metaclasses, exception handling, operator overloading etc.). Finally, Ruby supports a number of programming paradigms: other than object oriented, also functional, imperative, and reflective.
But in addition to all the things that the native Ruby language can do (and Ruby carries a pretty large standard library), perhaps what makes it so suitable (and useful) for programming of various types, and especially web programming, is the existence of a number of Ruby frameworks. A Ruby framework is collection of pre-written libraries, functions and controls that can be downloaded and used to make your programming task easier. In addition to a time saving, there is also a significant benefit in terms of programming efficiency and implicitly a more consistent programming style (since so much is pre-defined, one begins to use or utilize the paradigm of the underlying framework when writing a program).
Ruby-on-Rails is perhaps the most popular (certainly the most well-known) of the Ruby frameworks that is in use today, but there are also many others such as Nitro, Sinatra, Merb, and Camping. There are a number of things to consider when deciding on a framework. We will look at some of these things in detail before moving on to a description of some of the most common in use today, including the ones mentioned above. Since Ruby is primarily used for web programming, implicitly that will tend to be our focus.
Why Ruby in the first place?
Now, we have touched upon this a little bit in our introduction, obviously POLS and the sheer flexibility of the programming language makes it a natural choice for a number of programming tasks. There is also the fact that Ruby is in philosophy (and in other ways, syntactically) similar to a number of other programming languages such as Perl, Smalltalk, Lisp, Ada, and Eiffel – languages on which Ruby was based during its development. This makes it easy for programmers comfortable using these languages or their programming styles to quickly adapt to using Ruby. The same is true of programmers working with Python, Dylan, and CLU because Ruby is also similar to these in many respects. The strong focus on the object oriented paradigm makes it easier for anybody with a strong grasp of object oriented principles to quickly get cracking in Ruby. Finally, as mentioned before there is the flexibility of different programming paradigms, such as the functional, imperative and reflective (obviously in addition to the Object Oriented) that makes it attractive to programmers.
But there are other things going on under the hood that make Ruby such a popular choice, especially for web programming. It would be instructive to go into a detailed discussion of this, but we know this is neither the time or place for this so we will just mention two of the things that we think are most important. The first is something that is pretty obvious to most people experiencing a language like Ruby versus an extremely popular language like Java, and that is the scripting-like programming, which in addition to making code more human-friendly, also renders other advantages – everything in Ruby is an expression and everything is imperatively executed. What is less obvious and perhaps more important is the fact that with Ruby a strict adherence to the MVC (Model-View-Controller) architecture is possible. In fact, the power of the MVC architecture, and the capability of the Ruby frameworks to inherently support it (all 5 mentioned in the introduction above do so) is what makes Ruby so suitable for web programming.
A bit about the MVC
The core principle of the MVC architecture is to separate application logic from the user interface (UI). The View part, as the name suggests, refers to the UI part of the software, and this is completely separated from the application logic which along with the domain-specific data constitutes the Model. The Controller is in charge of receiving input from the UI and initiating an appropriate call on Model objects. Data is then returned by the Model which is directly delivered to the View (without any intervention from the Controller).
In the Web domain, the UI is HTML and the inputs received by the Controller are the GET and POST requests. The Controller then hands this over accordingly to certain Model objects, which then how to handle the request. The separation allows for a great deal of flexibility and the individual implementation of each piece of the architecture can be replaced without affecting the other pieces as long as the same interface is offered. This is especially important in business/commerce applications where policy changes can easily be applied by creating a different Model object, without touching the UI side.
MVC and Ruby frameworks
This kind of separation is what not only enables flexibility but in turn allows for rapid development of Web applications using Ruby frameworks. Most often the task of choosing the right Ruby framework boils down to the task of designing the proper MVC architecture (i.e. the individual pieces required for your particular application) and once these are well specified, this can guide you towards making more informed decisions regarding which framework to use.
To begin with it’s important to describe what the application domain is, that is what will the data look like. Are they records or are they files? What relationships, if at all, exist between different data elements and so on? This in turn will lead you to creating a new database for the application’s needs. Of course in many cases, you may already have the database available and that will automatically answer many of these questions for you.
The next task is to identify what can happen to this data. Can records be updated? Can they be deleted? And so on. It makes sense to spend a lot of time planning out all the possible ways in which you want user’s to be able to interact with data. Although, the Model part can be replaced easily, remember that the interfaces will still need to be consistent. Policy also plays a big role here.
Once you have elucidated all that you want the Model to do, you can proceed with the UI design. How do you want the application to appear in the Web-browser?
Ruby frameworks that support MVC (and most of them do) make the actual implementation of each of these pieces a breeze, because each of the three pieces of the architecture is handled by a specific sub-system, and if you have spent the requisite amount of time in planning you can pick and choose the specific functionality that you need for each sub-system. The skeleton is already implemented, you need to decide the details and you are away.
Choosing the right framework
The importance of the planning stage cannot be overstated, because the planning stage giving give you a road map as to what kind of framework you need. Essentially, this begins with the question of what you need to get done. What are the features and capabilities that are essential to the success of your project. This then gives you the outline for what you need.
Once you have the outline, there are several other things that you need to consider. Does a given framework have a strong support system and community? Is it used by a number of people? (Usually a more popular variant, or one that has been around for longer is also more likely to have a stronger support system and community.) Another related consideration is how well a framework is documented. In many cases there might be situations where your development team either has previous experience working with a certain kind of framework, or a certain style of Ruby programming, and this can direct your search for a framework.
If starting from scratch, then things such as how easy a particular framework is to use and understand, as well as how easy is it to develop and deploy, become important considerations. The development and deployment speed are also important considerations when not starting from scratch depending on the project timeline. Perhaps one of the things that is sometimes underrated is how comfortable you are using a particular framework.
Generally, to avoid errors/bugs and to ensure the stability of your web application, it makes sense to use a popular solution since finding answers to common questions and fixes for common solutions is easy. The most popular solutions (and those that have been around for a long time) have also been extensively tried and tested, ensuring a certain peace-of-mind for developers using it. And this, clearly, has something to do with that comfort aspect.
Compatibility checks (before installing a framework), and making sure that the framework has been installed and is functioning properly will ensure that once the development cycle is underway it will be relatively smooth sailing – at least in terms of the framework aspects – the problems of debugging the non-framework parts, and ensuring that you are using the framework in the right/desired way will remain, but don’t worry, these will surely get resolved as your project progresses (more so in the case of readily available documentation and strong support).
Ruby on Rails is perhaps the most popular Ruby framework that is in use today, and with good reason. Ruby on Rails was the framework that popularized the MVC approach as it relates to the task of web programming. This is done primarily by the Ruby on Rails MVC framework that consists of the Model (ActiveRecord), View (ActionView) and Controller (ActionController) sub-systems. It is open source and comes with a rich set of features including: AJAX support (via Prototype/script.aculo.us JS frameworks); a host of testing (Unit, Functional and Integration), security, caching and form-validation frameworks; internalization and localization functionality; and there are also pretty standard features such as DB migration frameworks, MVC Push capability, etc.
Ruby on Rails emphasizes agile development, “Convention over Configuration” (developer only needs to concentrate on the non-conventional aspects of application development) and “Don’t Repeat Yourself” (information is located in a single, unambiguous place). Since it has been around for a while, there is a well-defined API, extensive documentation as well as tutorials all over the web and finally a vibrant and supportive community.
Nitro is actually a framework that was around before Ruby on Rails became popular. There are a number of web developers who still swear by it. One of its finest features is a powerful template system that has a pipeline of configurable transformation steps. It is open source and along with the template style programming, there is the option of using the MVC approach as well. Og is the persistence layer (or object relational data mapping; ORM) that works with Nitro.
Nitro is comparable in its feature set to Ruby on Rails including AJAX support, testing frameworks, MVC Push, caching frameworks, security frameworks, internalization and localization, DB migration and more. However, its support and documentation is suspect, and in recent times interest in Nitro seems to have waned.
Merb is probably the second most popular framework in use after Ruby on Rails these days. One of the most interesting things about Merb is that it chooses not to make ORM, Templates, etc. frameworks/functionality part of the native system. These can be added via extension plug-ins and this allows the developer the flexibility to use whichever solution he/she prefers (or what makes sense for a given project). It does have a good feature-set that is part of the base system. It is an MVC based framework and has some of the best documentation (including useful getting-started tutorials).
At less than 4kb code size, Camping is one of the lightest Ruby frameworks around. In fact, it is one of the developers’ stated goals to always keep it below 4kb code size. It once again follows the MVC philosophy and provides a single file in which to carry out the development of the entire application (although the separation between each sub-system is still maintained). The developers also suggest that once initial or prototype development is completed in Camping the project can easily be migrated to Ruby on Rails. So in some cases Camping is a precursory development environment for Ruby on Rails.
Camping does not have AJAX support, internalization and localization frameworks, nor security, caching and form-validation frameworks, but has pretty much other necessary functionality such as DB migration, Testing frameworks, ORM, etc.
Ramaze’s emphasis is on simplicity. Ramaze also has a strict adherence to modular design and having minimal dependencies between different modules. Ramaze comes with a templating system called Ezamar and also has a fairly full-featured support for MVC applications.
Sinatra is a Ruby framework which like Camping is perhaps more suited for prototype development than actual business applications. It does, however, have a pretty standard set of features including MVC support, DB migration, Template and Caching frameworks. It does not have AJAX support, nor security and form-validation frameworks.
IOWA is another framework that has been around for a long time. It has support for both Event based and Cluster based modes of operation. Interest in IOWA has also slacked in recent years.
Halcyon is another lightweight framework whose aim is to support service-oriented applications (SOA). It has AJAX support through the JSON interface, and overall is a very well documented project and has a strong support community.
Waves seeks to provide an alternative solution for applications that do not need an MVC architecture. Thus, it has support for such things as AJAX, Adobe Air, mashups, OpenID, rich-client mobile apps, etc. This is done through a rich DSL. Waves’ developer speaks of the concept of request lambdas which are basically request mapping into a certain block, which results in a certain level of flexibility by removing some of the responsibilities of the Controller and placing the emphasis more on mappings. However, note that this is a subtle or implicit modification to the MVC pattern, and so use only after you have a good grasp of what’s going on and are confident that this is exactly what you need.
Ruby Web Application Framework (RubyWAF) is based on Jakarta Structs and enables web/wap application development. It can also serve as a starting point for developing custom Ruby frameworks.
It is a Network I/O and Event Management system for Ruby.
Webby is a Content Management System, which the publisher’s call a website management system because they think it is not big enough.
Like Webby Radiant is an open source Content Management System.
And finally little off-beat, for Linux enthusiasts: Ruby-GNOME2, a set of Ruby language bindings for the GNOME 2.0 development environment.