Transitioning to JavaScript from Ruby

Placido Wang
8 min readMar 10, 2020

Learning a language is hard. This applies to both spoken and programming languages. If you’ve learned one language however, it may be much easier to pick up a new one, depending on how similar their roots or paradigms are. If you’re an English speaker and you want steak fajita tacos from an authentic Mexican restaurant, there’s a direct translation for that. There may be some differences beyond just syntax, but if you said “Carne fajitas tacos” instead of “Tacos de fajita de carne”, a native speaker would know what you meant.

You do mean these, right?

The same can be said of programming languages. Sort of. While it’s true some concepts may be the same between languages like variable assignment and iterating through a list, every language has its distinct set of rules that you must follow. Even languages falling under the same programming paradigm can have drastically differing approaches to the same functionality. Unfortunately, this causes a lot of frustration when it comes to transitioning to a new programming language, and creates scenarios like Googling “How do I reverse a string in JavaScript with one method”, quickly followed by “CAN I reverse a string in JavaScript with one method”.

This happens a lot when going from Ruby to JavaScript. Ruby is typically much cleaner when it comes to readability. It also offers many built-in methods that make it easy for a programmer to get the program to do what she or he needs, such as .digits to get an array of all the digits in a number, or .has_value? to check if a value exists in a hash. In Ruby, you can write str.reverse to reverse all the letters in a string. Conversely, JavaScript has a reverse() method, but it only works on arrays, so if you were to accomplish the same thing, you might write str.split("").reverse().join("");. Compared to JavaScript, Ruby is much simpler and more human.

However, because Ruby is more human and more abstract, it is farther away from machine code, and therefore less efficient for computers to process. Ruby being slower and more limited means less scalability, leading major companies such as The New York Times, LinkedIn, Uber, and PayPal to switch from Ruby to JavaScript. Ultimately, the ease of use Ruby provides is excellent for lowering the barrier of entry for aspiring programmers, but it comes at a price.

There are other strengths JavaScript offers over Ruby that I won’t get into, but the point is many programmers transition from Ruby to JavaScript once they’re comfortable with Ruby for a reason. However, the transition can be rough as JavaScript is much less forgiving. I’ve outlined some differences that may catch a Rubyist off guard when starting to learn JavaScript, plus some guidelines and tricks that I’ve learned or found useful at some point. Hopefully this will make the migration (pun intended) a little easier.

Truthiness

In Ruby, there are only two values are falsy:

nil, false

In JavaScript, there are six values that are falsy:

undefined, null, NaN, 0, "", false

Additionally, because JavaScript is a loosely-typed language, you may get evaluations that may seem strange like:

1 == "1"; // truthy

1 === "1"; // falsy

[]; // truthy

[] == true; // falsy

[] == 0; // truthy

So what gives? JavaScript’s == is not the same as Ruby’s ==. In JavaScript, ==, checks to see if the values match, but not the data type. When using ==, JavaScript will try to convert one value to match the other value’s type, called implicit type coercion, and perform a loose equality comparison. When you want to check that the values are exactly the same, use === to perform a strict equality comparison. Ruby also has a === operator, but it’s a completely different thing.

Implicit Return

In Ruby, calling the following function

def sayHi
"Hi"
end

returns "Hi" . It knows that you want to return the last line in the function. This is called an implicit return. But in JavaScript, calling the following function

function sayHi() {
"Hi";
}

returns undefined. This is because JavaScript, for the most part, doesn’t return anything unless you tell it to, using an explicit return. It may sound like Ruby is “smarter” in this example, but on the other hand, JavaScript requiring you to write a return makes it very clear to someone who is reading your code exactly what you want your function to return. In my experience, a common theme in JavaScript philosophy is to be extremely explicit about how your code is written. The clearer the better. Take the following code for example.

function positive_or_negative(num) {
if (num > 0) {
return "Positive";
} else if (num < 0) {
return "Negative";
} else if (num === 0) {
return "Neither!";
}
}

The last else if (num === 0) conditional can be completely replaced with a simple else and the function would work exactly as intended. However, by explicitly specifying what the conditional is, you are being extremely clear about your code’s functionality. You don’t need to second-guess or to check all the previous conditionals to figure out when the last block of the if statement is supposed to execute. This is especially important with complicated functions when you or your team are trying to understand your code at 3 AM and trying to use or modify it. If your function is simple enough or if your else condition can’t be easily defined, you can get away with just using else.

I’ve gone over two very important, albeit nuanced, principles in JavaScript that may cause frustration, but with enough time spent and familiarity, the reasons they are in place will be clear. Now, here are a few tips I found useful in my own code.

For…of Loops

If you came from Ruby, you may have had a bit of a culture shock when you first saw this:

const words = ['Bubbles', 'Stars', 'Kitty'];
for
(let i = 0; i < words.length; i++) {
console.log(array[i]);
}

That’s a lot of weird characters we don’t normally use in our normal human lives, organized in a very specific way. Unfortunately, you can’t get away from needing to understand and memorize this very specific piece of code. However, when it comes to enumerable objects, there are other forms of the for loop that make it a little easier on the eyes:

for (const word of words) {
console.log(word);
}

This is actually preferred if your intended block of code needs to be run exactly once for each element in your array. It’s cleaner, and it’s clearer what you’re trying to do. Just remember that word is a placeholder, naming what each element in the array you’re iterating through is, not a variable that you’ve assigned earlier.

There’s also a for…in loop that’s generally used for objects, since the placeholder gives you access to the keys in your object. You can use a for…in loop on an array, but it will just give you the indexes.

Arrow Functions

If enumerable methods were your thing in Ruby, check out arrow functions in JavaScript. They function much the same, allowing you to call a block on each element in an enumerable object. Sound familiar?

const words = ['hello', 'WORLD', 'Whatever'];
const downcasedWords = words.map(word => word.toLowerCase());
// ["hello", "world", "whatever"]

Again, a placeholder is used for the elements in the array you’re iterating through. Here’s another example:

const nums = [5, 10, 15, 20];
const
sum = nums.reduce((a, b) => a + b, 1);
sum; // 51

Check Truthiness of a Value

Let’s say JavaScript datatypes and truthiness has got your head spinning. You could write a basic function to check a value’s truthiness:

function checkTruthiness(variable) {
if (variable) {
return "True";
} else {
return "False";
}
}

However, you can also use this:

!!variable;

The first ! converts the variable into a boolean, but of course it will be the wrong truthiness. The second ! fixes that by switching it back to the correct truthiness.

Filter Falsy Values

Here is a quick way to remove all falsy values from an array:

const array = [1, "Fish", [], 0, "Seven", "", true, false];
array.filter(Boolean); // [1, "Fish", Array(0), "Seven", true]

This is similar to array.compact in Ruby, although this only removes the value nil.

Assigning Multiple Values At Once

Let’s say we have a string and we want to assign each word to a variable. We might write something like this:

const str = "Wish you were here";const words = str.split(" ");
let word1 = words[0];
let word2 = words[1];
let word3 = words[2];
let word4 = words[3];

However, thanks to the power of destructuring assignment, we can instead write this:

let [word1, word2, word3, word4] = str.split(" "); 

We can even get fancy with arrow functions:

let time = "13:21:03";
let [hours, minutes, seconds] = time.split(":").map(part => parseInt(part));

However, while we are getting more concise, we are also straying away from being legible. In this case, taking multiple lines to assign each value may be preferable. Remember to balance your goals.

Get Unique Values From an Array

JavaScript doesn’t have a built-in function like Ruby’s .uniq for when you want the unique values of an array, but the next time you’re in such a position, try this:

const array = [0, 1, 'Apple', 'Tuna', 1, 'Apple', 'Nicolas Cage'];
const uniqueArray = [...new Set(array)]; // [0, 1, "Apple", "Tuna", "Nicolas Cage"]

This is because a set is a data set that can only have unique values. Combined with the spread operator, we can get a concise, efficient way of filtering out duplicate values.

I hope you learned a few things about the nature of JavaScript or a few helpful tricks. More importantly, I hope you learn to love JavaScript, or at least bear with it if you’re still struggling. Eventually, you’ll be able to harness its power in computing efficiency and web app integration. You may get a few cuts and bruises on the hike up to the top of the mountain but it’ll be a worthwhile endeavor.

--

--