Introduction

Ruby has been my primary development language for the last seven years of my job. It wasn’t a language I picked, but was already in use for the automation framework I work on. Over those years I’ve come to appreciate a lot of the simplicity Ruby provides.

Ruby can be used for anything from a simple script, to an automation framework, to a complex web application. All of this power comes in a syntax that is very easy to learn. In addition to the simple syntax comes duck typing. Duck typing means that you don’t have to explicitly deal with variable types, Ruby will treat variables as the type they are. If it looks like a string, and acts like a string it is a string.

Brief History

Ruby as a language was officially released in 1995 by Yukihiro Matsumoto. It is written in C and intended to be an object oriented scripting language. It was designed to fill the gaps that he felt were present in languages at the time like Python and Perl.

The language has always been object oriented allowing for classes, inheritance, and mixins from the original release. Subsequent releases have expanded that functionality and added performance improvements. The improvements in performance have been a major focus of Ruby 3.0.0 which is to be three times faster than Ruby 2.0.0.

On the Ruby website you can find a lot of information about the language. The website contains information like release versions, of which major releases have recently come out on Christmas. There is also a link where you can try ruby out directly in your browser.

Ruby also has a wide variety of runners allowing a wide choice in interpreters. The original interpreter is MRI (Matz’s Ruby Interpreter) which is built in C to run the Ruby Virtual Machine. MRI has been replaced by YARV (Yet Another Ruby VM) in more recent releases. Beyond the C implementations there is also JRuby written in Java and MacRuby written in Objective-C. This wide range of Ruby interpreters makes it easy to deploy Ruby to a wide range of systems.

Beyond the base language there is also a large and diverse set of libraries called Gems. Ruby Gems cover functions from as basic as making API calls to as complex as building a Neural Network. Most of the Gems are written in Ruby, but some make use of C libraries directly as well.

Uses

Ruby is designed to be a fun languages for software developers. In my time using it I would say that the fun and ease of use makes it a versatile tool. I have personally used it for a test automation framework running against web browser, Android apps, iOS apps, Windows programs, and MacOS programs. All of those tests against all those targets are in a single Ruby application. Ruby made it fairly easy to string together the Cucumber tests with the Appium, Watir, and Seetest drivers.

The second major use of Ruby that I have done is using Ruby on Rails to build a web application. Rails is a web framework for Ruby that makes it very easy to get a web application based on the MVC pattern up and running. Not only does it provide generators to set up the boiler plate code, it also allows you to leverage more complex functions of Ruby very easily. From start of MVP (Minimum Viable Product) for simple web applications can be done very quickly in rails between the initial startup helpers and generators. I have used it for things from API’s to webpages, to a Slack Bot.

The final use case I have used Ruby with is the one I’ve had the most fun with. I have used Ruby to build dozens of little helper tools for various work I’ve needed to do. From building a tool to process metrics to distill useful information to basic ML work to aid in triaging automation failures. Each time I’ve come across problems a little more complex than can be quickly solved by hand Ruby has been there as a tool to work it out. With the various Gems available to Ruby you can make API calls, read csv files, and handle basic ML use cases with ease. Each tool has taught me something new about the language and been enjoyable along the way.

Examples

Hello World

Hello World is the standard starting example. In Ruby that example is very quick and simple. So simple it’s a single line.

puts "Hello World"

Class, Inheritance, and Variables

Ruby provides a simple and easy to use syntax for both creating classes as well as handling inheritance. Also a part of the class structure is the various levels of variables. Ruby has global, class, instance, and local variables. The variables have their level set by the token or lack of that they start with.

class Example
  def initialize(item)
    @item = item
  end

  def show
    puts "I am an example #{@item}"
  end
end

ex1 = Example.new("ruby class")
ex2 = Example.new("variable check")
ex1.show
ex2.show

When you run the example it will output the following.

I am an example ruby class
I am an example variable check

Next is an inheritance example that will also show how class variables work.

class Animal
  def initialize(sound)
    @sound = sound
  end

  def speak
    puts @sound
  end
end

class Dog < Animal
  @@diet = "beef"

  def initialize
    super("woof")
  end

  def set_diet(food)
    @@diet = food
  end

  def eat
    puts @@diet
  end
end

rover = Dog.new
spot = Dog.new

rover.speak
spot.speak

rover.eat
spot.eat

rover.set_diet("chicken")

rover.eat
spot.eat

In this case the diet is a class variable on the Dog class. If the variable is changed for one instance of the class it changes for all instances. That means you will get the output below.

woof
woof
beef
beef
chicken
chicken

Modules and Mixins

Ruby handles name-spacing with modules. These can be used to store methods that you find helpful and want to reuse. These methods can be set to be usable directly from the module or designed to be mixed into a class.

module Helpers
  def self.add(a, b)
    puts a + b
  end

  def self.increment(a)
    puts add(a, 1)
  end
end

Helpers.add(2, 3)
Helpers.increment(6)

This simple example will produce the following output.

5
7

The next example shows mixing a module into a class. This makes it easy to create a portable set of functions that you need in multiple classes where inheritance would not be the best route.

module ClassHelpers
  def show
    puts @message
  end
end

class Example
  include ClassHelpers

  def initialize(msg)
    @message = msg
  end
end

ex = Example.new("Hello World")
ex.show

This will print “Hello World” like the very first example.

Meta-programming

Ruby’s options for meta-programing are some of the most fun I’ve had with the language. It is also the way to easily get lost when trying to be too clever. Ruby allows you to call methods based on strings, create methods at runtime, and other dynamic options. The first example will be calling a method from the first class example referencing it with a string instead of the direct method call.

class Example
  def initialize(item)
    @item = item
  end

  def show
    puts "I am an example #{@item}"
  end
end

ex = Example.new("ruby class")
ex.send("show")

This will print “I am an example ruby class” the same as if the show method had been called directly.

The next example will sow how methods can be dynamically created. I have used this in cases where basic method information is loaded from a YAML file then used to generate more complex methods.

class Teacher
  ["plan", "teach", "grade"].each do |action|
    define_method("#{action}_lesson") do |argument|
      puts "I am #{action}ing the lesson on #{argument}"
    end
  end
end

teacher = Teacher.new
teacher.plan_lesson("lit")
teacher.teach_lesson("math")
teacher.grade_lesson("social studies")

The result will be what is shown below. While not the best English it shows the potential of using meta-programming in Ruby.

I am planing the lesson on lit
I am teaching the lesson on math
I am gradeing the lesson on social studies

Final Thoughts

I would recommend Ruby to both new and experienced developers. It’s a fun language to use in a large variety of situations. It has the power to be used in very large complex applications. It has the ease of use for quick scripts to automate simple tasks.

For beginner developers it provides a simple syntax with a variety of style options. It doesn’t constantly run into type errors or other strict language issues. It almost looks like pseudo-code you might see in learning situations. The fact Ruby is a scripting language also means you can start with simple single file scripts with just straight execution and grow into objects and functions.

For more experienced developers it’s nice to be able to use a language where you don’t feel constrained by the syntax and rules. In this case the simplicity aids in working out complex problems without spending most of your time in a reference document. With Ruby you can spend more time writing code instead of looking up the exact syntax you need.

For anyone who works with lots of one off tasks I would recommend giving Ruby a look. You may just find that this simple language brings back some joy and relaxation in coding again.