RUBY

Autoloading and Utility Methods – Part 3


This is the third part of Building an MVC Framework with Ruby. The topics we’ll cover are:

  • Part 1 – Rack Deep Dive

  • Part 2 – Set up a Basic Framework 

  • Part 3 – Autoloading and Utility Method

  • Part 4 – Better Routing

  • Part 5 – Render, Redirect & Before_Action Methods in Controllers

  • Part 6 – Extract Complexities out of View with Helpers

  • Part 7 – Reduce Rework with Generators

  • Part 8 – Set up ORM for Read/Write to Database 

  • Part 9 – Generate Database from Schema

  • Part 10 – Set up Migrations

The source code for this post is available on github.

In this post, we will look at how to autoload classes and we will create some utility methods that will be used throughout this series

  • Set up code quality check tools
  • Utility Methods
  • Autoloading classes

1. Set up Code Quality Check Tools

We will be using rubocop and code climate to ensure we are shipping quality code.

1.1 Rubocop

RuboCop is a Ruby static code analyzer. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide. The gem reports style violations through the command line, with lots of useful code refactoring goodies such as useless variable assignment, redundant use of Object#to_s in interpolation or even unused method argument.

It’s divided into 4 sub-analyzers (called cops): Style, Lint, Metrics and Rails. You can define which cops to use, as well as which files to exclude/include and tweak various other configuration options in a .rubocop.yml file.

You can run rubocop using bundler in your project by adding the gem to your gemfile.

Note: You don’t need to require it.

Check out this link for more information about rubocop.

1.2 CodeClimate

Code Climate consolidates the results from a suite of static analysis tools into a single, real-time report, giving your team the information it needs to identify hotspots, evaluate new approaches, and improve code quality.

Check out this link and this link to know more about code climate and how it works.

2 Utility Methods

Let’s create a few utility methods that we will be using throughout our framework. Our utility methods will live in a file called utility.rb.

2.1 snakize

Open lib/utility.rb and paste this code inside it.

We are basically opening the String class and adding a method called snakize to it. This method converts any string(in camelcase) to it’s snake case equivalent. It achieves this by following the rules below.

First, snakize calls gsub (replace-all) on double-colons with slashes. This means a constant like “Namespace::Controller” means you want a subdirectory. In which case, it will transform the string to “Namespace/Controller”

Next, it gsubs any two or more consecutive capital letters followed by a lowercase letter… And replaces it with 1_2. If youʼve used regular expressions, you know that 1 means “the first thing in parentheses” and 2 means “the second thing in parentheses”. In which case, it will transform “REGULARExpression” to REGULAR_expression”

Next, it gsubs from lowercase/number followed by uppercase to lowercase/number-underscore-uppercase. In which case, it will transform “PersonController” to “Person_Controller” or transform “Person8Controller” to “Person8_Controller”

Finally it turns all dashes into underscores, and converts everything to lowercase.

2.1.1 write test for the snakize method

Create a folder called unit in your spec folder. All your unit test will recide there.

Open spec/unit/utility_spec.rb and paste this code inside it.

Commit your changes

2.2 camelize

open lib/utility.rb and add this method to String class.

This method converts a snakecase string to it’s camel case equivalent. It first checks if the string is a snake case string and returns it otherwise. If the string is a snake case string, it split’s it by “_”, capitalize each word and joins the string back. So a string “person_controller” will be converted to “PersonController”.

2.2.1 write test for camelize method

Open spec/unit/utility_spec.rb and add this code inside it.

Commit your changes

2.3 constantize

open lib/utility.rb and add this method to String class.

This method convert’s any string to it’s constant equivalent. eg “PersonController” will be converted to PersonController constant. It achieves this using a little bit of ruby metaprogramming magic Object.const_get which finds a constant with the same name as the string passed as it’s argument.

2.3.1 write test for constantize method

Open spec/unit/utility_spec.rb and add this code inside it.

Commit your changes

 

2.4 pluralize

open lib/utility.rb and add this method to String class.

This method convert’s a string to it’s plural form. The rules I used to pluralize a string is found here.

2.4.1 write test for pluralize method

Open spec/unit/utility_spec.rb and add this code inside it.

 

Commit your changes

You can test utility_spec.rb using

or you can use this

to run the test in documentation format.

You can check for style violations at this point using rubocop. Check the github repo for the .rubocop.yml configuration used.

3.0 Autoloading Classes

Let’s add a neat automatic loading for our gem for cases when it sees something it thinks it recognizes. If it sees PersonController and doesnʼt have one yet it loadsapp/controllers/ person_controller.rb.

You may already know about Rubyʼs method_missing. When you call a method that doesnʼt exist on an object, Ruby tries calling method_missing instead. This lets you make invisible methods with unusual names.

It turns out that Ruby also has const_missing, which does the same thing for constants that donʼt exist. Class names in Ruby… are just constants.

Now that you can convert a camel-case constant name to a snake case file name, letʼs add magic constant loading to Zucy.

Open lib/zucy/dependencies.rb and paste this code.

3.1 Write test for the const_missing method

Create a folder called helpers in spec/unit folder and create the following files and their corresponding classes inside the file.

  • person.rb
  • todo.rb
  • person_controller.rb

Open spec/unit/dependencies_spec.rb and paste this code.

Notice that we added the helpers folder to our load_path on line 2.

With this, we have added a bunch of utility and helper methods to . However we still have a long way to go. Keep calm and wait for the next post.

The source code for this post is available on github.

In the next post, we will implement a more sophisticated routing. Something similar to the routing we have in rails.

Please, if you have any questions or observations, let me know in the comments section below:

 

 

Ikem Okonkwo

About Ikem Okonkwo

Ruby Evangelist, .NET Advocate. Trainer at @andela. Passionate about education and lifelong learning. Loves good food and soccer.