Embrace the Power of Ruby: A Programming Superhero
Tags: ruby, rails, programming, coding
Published: 2023-07-06 10:47:26

If programming languages were 🦹‍♀️ **superheroes** 🦸‍♂️, Ruby would be the master of adaptability.

It fluently switches between paradigms like a skilled shape-shifter, empowering developers to solve problems using different programming styles, be it object-oriented elegance or functional simplicity.

## Introduction

In this post, we'll cover the different programming paradigms present in Ruby.

But first, let's have a quick reminder of what is a paradigm.

## What is a paradigm?

From Wikipedia:

> In science and philosophy, a paradigm is a distinct set of concepts or thought patterns, including theories, research methods, postulates, and standards for what constitutes legitimate contributions to a field.

**Let's have a look at the Object-Oriented Programming paradigm in to see a concrete example of what is a programming paradigm.**

## OOP in Ruby

This paradigm is composed of the following concepts:

- objects and attributes
- data encapsulation
- data access control
- methods
- data manipulation via `this` or `self`
- class as type
- first-class objects
- etc...

In Ruby, all these concepts are present as built-in features.

These are considered the backbone of the language.

As a result, Ruby is fundamentally tied to the Object-Oriented Programming paradigm.

Cool!

Now that we grasp the concept of programming paradigms, let's examine the range of paradigms that can be linked to Ruby, depending on its language features.

## Programming Paradigms in Ruby

Here, we'll discuss 3 programming paradigms Ruby can handle:

1. the Procedural programming paradigm
2. the Functional programming paradigm
3. the Generic programming paradigm

### The Procedural programming paradigm

This paradigm is based on the concept of procedure calls.

In computer programming, a procedure is mainly assimilated into a function.

A function - in opposition to a method - is defined from outside classes.

So, a procedure call can be seen as a function call.

In Ruby, functions don't exist.

But we can create methods outsides of classes

```ruby
self # => main

def procedure1
  "I'm processing stuff.."
end

def procedure2
  "I'm processing another thing.."
end

procedure1 # => "I'm processing stuff.."
procedure2 # => "I'm processing another thing.."
```

Here, `procedure1` and `procedure2` are defined from outside classes.

Then we call these methods procedurally.

In fact, these methods are still defined within an object: the `main` object.

This way to use Ruby is popular among the DevOps community.

Indeed, they often need to build scripts to interact with the systems they use.

### The functional programming paradigm

In the OOP paradigm, everything turns around objects.

In the functional programming paradigm, everything turns around functions.

There are 3 main concepts around functional programming:

- **Pure** functions
- **Higher-Order** functions
- **First-Class** functions


#### Pure functions

A **pure** function is a function that always produces the same output for a given input

```ruby
def pure_method(obj)
  obj * 2
end

pure_method(2)    # => 4
pure_method([42]) # => [42, 42]
pure_method('a')  # => "aa"
```

Here, `pure_method` always returns the result of the object passed as an argument, times `2`.

For a given input, the output will always be the same.

By intent, the functional programming paradigm is strongly related to the concept of `pure` functions – as side effects are the enemies of this programming paradigm.

#### Higher-order functions

**Higher-Order** functions are functions that can take a function as an argument or return a function

```ruby

add = -> (a, b) { a + b }

def process(operation, a, b)
  operation.call(a, b)
end

process(add, 1, 1)          # => 2
process(add, 'Bon', 'jour') # => "Bonjour"
```

Here, the `process` method takes an object that responds to `call` — a `proc` or a `lambda` for example — and passes `a` and `b` to `call`.

As it’s impossible to pass a method as an argument of another method, then we use a `proc` to bypass this issue.

#### First-Class functions

A programming language that proposes **Higher-Order** functions can be defined as a **First-Class** function programming language.

Ruby is not a **First-Class** object programming language.

But we can use `lambda`s and `proc`s to elegantly simulate the behavior of a function passed as an argument.

### Generic programming paradigm

Definition of Generic programming paradigm from Wikipedia:

> Algorithms and methods are written in terms of types to be specified later that are then instantiated when needed for specific types provided as parameters.

Ruby dynamic typing coupled with the Duck Typing design already provides all the necessary tools to apprehend Ruby as a generic programming language

```ruby
def gt(obj1, obj2)
  obj1 > obj2
end

gt(3, 2)         # => true
gt('bbb', 'aaa') # => true
```

Here, the `gt` method expects to receive 2 **comparable** objects as an argument.

The method doesn’t depend on the type of argument.

So this method is generic and can be used for any kind of comparable objects.

### Conclusion

Ruby, is a fully Object-Oriented programming language. But it also cherry-picks — and implements — concepts from other programming paradigms.

This approach allows Ruby developers to use this language in a wide variety of applications.

### Eager to learn more about Ruby

You can follow us on [x.com](https://www.x.com/RubyCademy) as we're very active on this platform. Indeed, we post elaborate code examples every day.

Additionally, we're currently finalizing our first online course: **Ruby Mastery**.

Join the list for an exclusive release alert! 🔔<br/>

🔗 [Ruby Mastery by RubyCademy](https://www.rubycademy.com)

 <center>💚</center>