Web Basics with Ruby — Sinatra Battleships Project Part 1

I have created a functional version of a console Battleships game in Ruby, where each ‘round’ you are asked to pick coordinates on a 10x10 grid to try to hit hidden boats. In the current formulation, you have 20 or so guesses to hit 9 boats of differing lengths.

My new task is to implement a web-based version of the game using Sinatra.

Web Frameworks and Rack for Ruby

As I have described in a previous post, there is not really a concrete definition of what a ‘framework’ is, but programmers tend to think of this as a set of libraries, software tools and conventions which when put together provide an ecosystem enabling easy development of a certain type of application, with much of the boring, lower-level commonalities already pre-programmed so that the developer can focus on the juicy code. A web framework therefore provides you with the tools you need to develop web applications, taking care of the common ‘background’ details for you so that you do not have to reinvent the wheel each time.

The main modern Ruby web frameworks, including Ruby on Rails and Sinatra, are built on top of an architecture called Rack. This is a simple web server interface which essentially handles mundane HTTP communication details between web servers (the systems hosting websites, such as Apache and WEBrick) and web application frameworks. That is, behind the scenes, it deals with the underlying request-response of HTTP calls — it allows web frameworks to ignore the implementation of these and build more exciting code on top. I will explain in detail how Rack works in a later blog post.

Sinatra vs Ruby on Rails

Sinatra is a package for Ruby that can be installed via the usual gem install sinatra command in terminal, or via bundle install if you are using Bundler.

The most commonly used Ruby web framework is, of course, Rails. Rails is a full tool suite which abstracts much of the implementation details away so things just work and appear ‘like magic’. For example, the command rails new blog will auto-generate a large set of directories and files so that the entire structure of the project has already been pre-planned for you. There are advantages and disadvantages to this approach. Coders can get straight to programming the interesting bits of code, and can jump into any Rails project and understand the architecture immediately — everything has its defined place. However, there is little flexibility and if something goes wrong, sometimes coders will have a hard time figuring out what the problem is, if much of the setup was abstracted away.

Sinatra, on the other hand, is lightweight and minimalist. You are given a few key tools which enable you to build projects. As little is pre-defined, coders come up with their own project arrangements— structurally Sinatra applications can end up looking quite different, while Rails applications will look largely the same.

It is illustrative that Rails is a web application framework, while Sinatra is described on its website as a domain-specific language (DSL). This makes sense — Rails is ‘heavy’ and includes most of the pre-defined full stack tools you would possibly need for web development, while Sinatra aims to provide only pre-written key terms (methods, classes and so on) so you can build up your own project-specific language on top.

My mentors have asked me to begin by using Sinatra. It is said that Sinatra is more useful for learning the basics of HTTP and routing (as you are forced to get to grips with how to set these up without shortcuts) while Rails teaches you about resources and how to use a database. In any event, it seems sensible to begin with a barer framework which necessitates an understanding of the underlying web concepts before learning a system which works on shortcuts.

HTTP — How the Internet Works

I mentioned above that Rack is an architecture which facilitates request and response in HTTP. HTTP stands for HyperText Transfer Protocol. A protocol is the manner in which two things ‘talk’ to each other, a set of formal rules for communication. This is how the Internet works, on one level. A user types the address of a webpage into their browser. This address is referred to as a URL (Uniform Resource Locator) and will most likely have ‘http://’ at the beginning, which signifies that HTTP is the protocol which will be used. The browser sends a request for the webpage at the URL address, sent to the web server hosting the website with the webpage. The web server retrieves or generates a response and sends it back to the client browser, which renders (displays) the page to the user.

All webpages are written in HTML (HyperText Markup Language). The content of HTML documents are ‘marked up’ semantically, enclosed by tags. For example, headers, footers, different levels of headings, sections and line breaks are all explicitly stated, which enables any web browser on any device to render content correctly and consistently. Usually CSS (Cascading Style Sheets) is used in conjunction with HTML to manipulate the visual representation of the content as HTML defines only the semantic structure.

Webpages sent as responses to browsers’ requests might be static (i.e. completely pre-made and simply retrieved when requested) — or generated dynamically by the web application. This might be in the back end of the application (using Ruby, for example), or at the front end using Javascript.

One could say that the primary purpose of web applications is to produce HTML documents so that they can be sent to web browsers to be displayed to the end user (quoted from source).

Embedded Ruby

Sinatra is a Ruby DSL which essentially provides a language to enable you to write code to detail what should happen when a browser makes various requests. HTML pages must be sent back to the browser to be rendered and viewed by the user. These days, it is rare for pre-written, static HTML pages to be sent to the browser as they are — instead, HTML documents are generated on the fly on the basis of a template HTML document, potentially utilising some information about or provided by the user (perhaps their username or email address or data they have provided in a form). HTML itself can only set semantic markers — it cannot be used to calculate or resolve substantive code, so a scripting language must be used instead. For websites, this is often Javascript, but I will be using only Ruby.

Javascript can be ‘passed’ as a script directly into an HTML document, to be resolved and then sent on in final form as the response to the browser. In contrast, you cannot simply plonk any old Ruby code into an HTML document (this will not get resolved and would be sent as some kind of undefined plain text to the browser), and you cannot send a Ruby file as a server response.

This is where Embedded Ruby (erb) steps in. This is a ‘templating system’ that ships with standard Ruby (there is not even a need to require it from the standard library at the top of files) which enables Ruby code to be embedded into text documents — most commonly into HTML documents. I will detail exactly how this works in a later blog post.

Connecting the dots

So how does it all connect together? To build a web application version of my Battleships game, I will need to make a Ruby file (usually called something like ‘app.rb’) which will tell the web server what to do when a browser makes a request to it — i.e. where to go to generate the HTML responses. This file will ‘speak to’ another file containing the rules of the game to ask it what to do with the user’s input. After the rules have calculated what to do, the app file will take this information to the Views directory. This will contain HTML templates, which can be used to generate a plain HTML document to send as the response back to the browser.

Emmet Plugin for HTML

As a quick aside, I have also installed Emmet for Vim. Emmet is the biggest HTML and CSS workflow tool of its type. It enables quick completion of tags and a host of other useful shortcuts. It is beyond the scope of this post to detail how this works but it is very useful whenever working with HTML and CSS and I recommend installing it.

--

--