From JavaScript to Ruby: A few of my favourite features
Tags: ruby, javascript
Published: 2019-02-01 12:47:22

---
title: From JavaScript to Ruby: A few of my favourite features
published: true
description: Coming from JavaScript to Ruby, I was excited to learn the language that promised to be "designed for developer happiness". Here are a few of my favourite features!
tags: Ruby, JavaScript
---

![Ruby](https://thepracticaldev.s3.amazonaws.com/i/ag34t8l3d6abb8onugfn.jpg)

Coming from JavaScript to Ruby, I was excited to learn the language that promised to be "friendly to developers" and "designed for developer happiness". I discovered a language which, like JS, is dynamic, object oriented and general purpose. Like JS, it also offers lots of ways to do the same thing, enabling the developer to have a fair amount of stylistic autonomy (if you like that kind of thing).

Ruby has a fairly low learning curve, since it seems to have been designed with lots of sensibly-named, consistent and easy to use methods, and it also has no concept of asynchronicity out of the box, making code easier to reason about than JavaScript.

Here are a few things I've noticed which I think are pretty neat about Ruby, in comparison to JavaScript!

## Being able to check memory location

Unlike in JavaScript, Ruby lets you inspect the location in memory of a value with the `object_id` method:

For example, if we look at the object ID of 2 hashes:

```ruby
a = {name: 'Harriet'}
b = {name: 'Heather'}
puts a.object_id # 6478367
puts b.object_id # 6471222
```

Those numbers are memory addresses. The actual addresses aren't that useful but it might help to see when you're dealing with two references to the same location in memory, or references to separate locations in memory.

I've never used this in a practical sense, but it was helpful when I wanted to explore the difference in how Strings and Symbols work in Ruby (see next section). There's no way in JavaScript to inspect where items live in memory, which has been annoying when I've been trying to demonstrate how JavaScript passes objects by reference, and primitives by value.

## Symbols

In JavaScript, you have a few of ways of creating a string, the first two here being the most common:

```javascript
let a = 'Hello world'
let b = "Hello world" // Functionally no different to using single quotes
let b = new String('Hello world') // Creates a String object
let c = `Hello world` // ES6 String Literal
```

In Ruby, there are also a few options:

```ruby
a = 'Hello world'
b = "Hello world" # Double quotes allow for string interpolation & escape characters
c = String.new('Hello world')
d = String('Hello world')
```

In Ruby, by default, all Strings are types of String Objects, and as Objects they occupy different places in memory, even if the contents of two or more strings is the same. Potentially a bit wasteful, storing the exact same information twice over!

You can check this by looking at the object ID of 2 identical strings:

```ruby
a = 'Hello world'
b = 'Hello world'
puts a.object_id # 6478367
puts b.object_id # 6471222
```

That’s where Symbols come in. A Symbol is created with a : at the beginning and means that any time the Symbol is used, it will reference the same value.

```ruby
a = :hello
b = :hello
puts a.object_id # 1111708
puts b.object_id # 1111708
```

This works great for single words, but you can even turn a longer string into a Symbol and increase efficiency with the `.to_sym` method:

```ruby
a = 'Hello world'.to_sym
b = 'Hello world'.to_sym
puts a.object_id # 92880
puts b.object_id # 92880
```

I use symbols over strings wherever I can, not just when I know a value will be used again in a program! Why not, when it’s easy to do and there’s nothing to lose?

## Simple loops ➰

In JavaScript, sometimes you just want to loop a set number of times. You don't care about the start point or the end point, as long as your code executes n times. However, you're forced to explicitly construct the conditions for iteration yourself, starting with i = 0 and defining when you want the loop to end:

```javascript
for (let i = 0; i < 10; i++) {
 // do stuff
}
```

In Ruby, you can simply do:

```ruby
10.times do
  # do stuff
end
```

It's a simple, less imperative way of executing code a set number of times.

## Functions are stricter about arguments

I like that in Ruby, you get an error if you give a function the wrong number of arguments. It just speeds up the process of debugging your code.

```ruby
def greet(name)
  puts "Hello, #{name}"
end

greet()

# wrong number of arguments (given 0, expected 1)
```

You can also name your parameters, and if they're not passed, or you pass something unexpected, you'll get an error:

```ruby
def greet(name:, city:)
  puts "Hello, #{name} from #{city}"
end

greet(name: 'Harriet', city: 'Manchester')

greet(name: 'Harriet') # missing keyword: city

greet(name: 'Harriet', city: 'Mancheseter', age: 27) # unknown keyword: age

```

## No function call parentheses

In JavaScript, you must use parentheses when calling a function, for example `add(1, 2)`.

In Ruby, parentheses are generally optional, which can sometimes lead to Ruby that looks very natural language-y and easy to read. For example, a testing library can provide a `to` method which, when used without parentheses, reads like this:

```ruby
expect(result).to be_null
```

Although it can get a bit confusing if you've got multiple arguments. For example, is `5` the second argument to `bar`, or the second argument to `foo`? Without brackets it's not clear:

```ruby
def foo(a, b)
  puts "in foo #{a}, #{b}"
end

def bar(a)
 12 + a
end

foo bar 55, 5 # wrong number of arguments (given 2, expected 1)

foo bar(55), 5 # Correct - 5 is the second argument to foo
```

Calling a function without parentheses also means we can do something like this:

```ruby
def greet(name = 'Harriet')
  puts "Hello, #{name}"
end

greet
```

See how just referring to the `greet` method actually invokes it with no arguments? This is how Ruby implements getter methods on objects. When you call `person.name` for example, `name` is actually a method on that object, which retrieves the `name` instance varaible. It's not simply an object property like in JavaScript.

One effect of parentheses-less method calls means we can't pass methods around as values, like we can in JavaScript. In JavaScript, we can do this:

```javascript
function greet(name) {
  console.log(`Hello, ${name}`);
}

const welcomer = greet;

welcomer('Harriet');
```

But in Ruby, trying to pass a reference to the method actually invokes it! So we end up with:

```ruby
def greet(name = 'Harriet')
  puts "Hello, #{name}"
end

welcome = greet # This line actually executes the greet function

welcome "Paula" # undefined method `welcome' for main:Object

```

## Just one way to create Classes

In JavaScript there is not really a concept of true classes, at least not in the way people from truly Object Oriented languages would expect them to be. Instead we have a the prototype chain, and at least 4 different ways of creating objects with shared methods and behaviour. This is super confusing, so I really like that Ruby just offers the one way to do it!

Creating class methods, class variables, instance methods and instance variables is much more straightforward in Ruby:

```ruby
class Person
  attr_reader :name, :title

  # Class variables
  @@legs = 2
  @@arms = 2
  @@diet = 'omnivore'

  def initialize(name, title)
    # @name and @title are instance variables
    @name = name
    @title = title
  end

  # Instance method
  def greet
    puts "Good day, #{title} #{name}!"
  end

  # Class method
  def self.describe
    puts "A person is a #{@@legs}-legged, #{@@arms}-armed #{@@diet}"
  end
end

jerry = Person.new('Jerry Jones', 'Mr')

jerry.greet

Person.describe
```

## Implicit returns

In Ruby, the `return` statement is optional, or can be used to return early from a function. If you omit it, the function will return the last evaluation.

```ruby
def double(nums)
  nums.map{ |n| n * 2 }
end
```

## Metaprogramming

This one's quite a big a topic and I don't know it that well so I'm only going to touch on it briefly. Metaprogramming means a program being able to modify itself at runtime, based on the state of the program at that time.

Rails uses Metaprogramming to allow us to do something like this:

`Book.find_by_ISBN("19742084746")`

You defined the `Book` class when you set up your Models, but nowhere did you defined the `find_by_ISBN` method. Defining a `find_by_x` for all your columns would be really tiresome; it's no wonder the Rails framework doesn't want to make you go to all that work. But Rails itself didn't add that method for you, either. How would Rails magically know what your Book instances needed a `find_by_ISBN` method?

Instead, when Rails sees you trying to use the `find_by_ISBN` method it will extract the `ISBN` part and attempt to match it to a column in the database, and if successful, will execute some code to find your item based on the `ISBN` column, responding as though `find_by_ISBN` were an actual method that had been defined on Book instances.

This is just one example of what Metaprogramming can do!

Personally I think it's pretty cool, and once you know it exists, you begin seeing it "in the wild" all over the place in Ruby. It's the foundation stone for being able to create DSLs (Domain Specific Languages) like Rails and makes Ruby extremely flexible.