Ruby vs. JavaScript — Exploring Datatypes and Mutability

Ricardo Ledesma
Aug 31, 2018 · 9 min read
“black and silver laptop computer on table” by Clément H on Unsplash

This will be a series of articles comparing Ruby and JavaScript for beginning to intermediate programmers. I hope you learn something along the way!

Contents

  • Defining terms
  • Ruby vs. JavaScript as a first language
  • Datatypes
  • Mutability
  • Pass-by-reference vs. Pass-by-value

Both Ruby and JavaScript are great languages to learn for a beginner.

Some terms you need to know before we start:

Variable: pointer or name given to a certain value in memory. So that value doesn’t have to be re-typed every time it is used.

full_name = 'Hermonie Granger'

Object: data-structure made up of key-value pairs. Keys are the unique identifier for some value.

headmaster = {name: 'Albus', age: 'over 100?'}

  • name and age are the keys.

Classes: blueprints for any objects that are created using that class

  • Blueprints as in any objects created will have the specified properties and methods dictated by the class
  • objects created using a class are called instances
# Ruby Class # # Defining a classclass Wizard  def initialize(name, house)    @name = name    @house = house  endend
# Creating an instance of Wizard (a Wizard Object)hermonie = Wizard.new('hermonie', 'gryffindor')

The Wizard class dictates that any created instances will have the properties name and house

  • These are specified when the instance is created (using the new class method)

This will be further elaborated on in a further article. This is just so you’re aware of the concepts.

Methods: reusable code that can be customized using variables (also called functions or procedures).

# Ruby Code
# Defining a method that shows a string (put string)
def introduce(name) puts nameend
# Calling introduce and passing a stringintroduce('Draco')# => 'Draco'

// precede lines of code that are commented out JavaScript (JS)

console.log is a method used to print values to the console (JS)

# precedes lines of code that are commend out in Ruby

=> is called a hash-rocket and represents what is returned from lines of code

(when used in Ruby comments)

Comparison

Ruby

Ruby is designed with the idea that programming should be enjoyable.

  • It’s an Object-oriented programming language which means that code is structured into objects and those objects communicate with each other. It is a very popular form of programming that can lead to organized, compartmentalized, and reusable code.
  • It’s syntax is clear, easy to read, and intuitive.

gets gets a string input, puts puts a string, repeating an action is simple (looping).

10.times do |n|  puts "number is " + nend
  • 10 times: put the string “number is ” with the current number in the loop.

What many beginners are taught in JavaScript:

for (var i = 0; i < 10; i++) {  console.log(i)}
  • Once you understand what all that means — it’s simple. It can seem very cryptic at first though.

JavaScript

The default language of the web and according to the annual Stack Overflow survey from 2017 — the most popular.

Stack Overflow Developer Survey 2017

  • Because of it’s popularity there are many free resources to learning JavaScript.
  • JavaScript has become more object-oriented in recent years but is actually a prototypal-based language which can create code that is simpler and less interdependent than OOP.
  • If you don’t know what any of that means, no worries — it all comes with time.

I would recommend JavaScript for the job opportunities but really you can’t go wrong learning either. Learning the fundamental programming concepts is more important than the language.

  • Also the more languages you learn, the better programmer you will become. Do stay consistent with one though and learn it in depth before moving on to another. Many recommend learning a stack (LAMP, MEAN, MERN) or a group of languages if you’re doing web development.

This article will give you a starting point for navigating all the needed technologies for back-end or front-end

The 2018 Web Developer Roadmap — codeburst

With that intro aside, let’s start with how data is stored in both languages

Datatypes

A data type is simply a category that tells the compiler (what turns your code into machine code) how to interpret the data.

  • Ruby and JavaScript are dynamically typed languages. This means that variables don’t have an explicit type and can be assigned and reassigned any type of value.
  • The data type of the variable is determined by whatever type is the current value of that variable

As opposed to statically-typed languages where type is explicitly stated for each variable and reassigning to a different value type leads to an error.

In the following — a variable is declared and assigned and reassigned data of different types

// Javascript //// String valuevar orphan = 'Harry'// Number valueorphan = 11;// Object valueorphan = {knownAs: 'The boy who lived', favoriteSport: 'quidditch'};# Ruby ## String valuedobby = 'house elf'# Hash valuedobby = {'warning' => 'Harry Potter must not go back to hogwarts!'}# FalseClass value (Boolean)dobby = false

the data type of orphan or dobby does not need to be explicitly stated beforehand and is not permanently set once the variable is defined

Both languages are flexible in what values variables can be assigned but have key differences in how the values themselves are stored in the computer’s memory.

In Ruby — everything is an Object and each data type is an instance of a class

  • The piece of data is said to be an object of that class
  • 4 is an Integer object
  • The data itself is the object (not the variable)

In JavaScript — some data-types are Primitives and the rest are Objects

Types found in both languages

  • String
  • Array
  • Symbol

Ruby Types

  • NilClass
  • TrueClass
  • FalseClass
  • Hash
  • Float (Numbers with decimal)
  • Integer (Whole numbers)

JavaScript Types

Primitives

  • Boolean
  • Null
  • Undefined
  • Number (Represents both floating point and integer numbers)

Null and Undefined both mean without value. However, Undefined should not be used by the programmer - only by the JS engine. Use Null instead.

Objects

  • Functions
  • Maps
  • Object

Determining Datatype

Ruby

Object.class

'seeker'.class 
# => String
{name: 'Ron'}.class
# => Hash
9.75.class
# => Float

JavaScript

typeof

console.log(typeof 9.75);
// "number"
console.log(typeof 'Expecto Patronum');
// "string"
console.log(typeof true);
// "boolean"

Mutability (How data is stored)

In JavaScript — primitive datatypes are stored differently from object datatypes

In Ruby — everything is an object but some datatypes are still stored differently than others

You may ask, why do I need to know this?

When changing or moving values around in your program. It is important to understand what values are actually being copied or changed

  • Understanding how information is managed by a language will help you understand the state of your program.
  • In other words — the data and which functions are changing it

Every value in a program has a place in memory

If you want a more in depth explanation and history of the concepts of place and value in programming, I highly recommend this talk by Rich Hickey (the creator of Clojure)

The Value of Values with Rich Hickey

The value in that place can either be updated or it cannot

  • A mutable value is one that can be modified
  • An immutable value is one that cannot be modified

In Ruby the only data types that are immutable by default

  • TrueClass, FalseClass, nil
  • Numeric
  • Symbol

In JavaScript that only datatypes that are immutable are primitives

How these values are copied or passed to functions depends on the datatype and whether it is considered immutable

Pass-by-reference vs Pass-by-value

Copies by-reference means that an additional pointer is being created to the same place in memory

  • Two variables with the exact same value

Copies by-value means that an additional pointer is being created with a new location in memory

  • Two variables with different values

Ruby

In ruby object_id returns the memory address of that object

# Immutable values ## Copying a value by-referencehorcruxes = 6souls = horcruxeshorcruxes.object_id == souls.object_id# => truelord_voldy = falsetom_riddle = lord_voldylord_voldy.object_id == tom_riddle.object_id# => true

In the previous examples — there is only one value (type Integer and FalseClass) and “copies” are made by creating another pointer to that value

When copying mutable values in Ruby — the behavior is similar to immutable values

  • Both variables point to the same value. If the value is modified but not reassigned the changed value is visible in both variables.
# Creating a copy by-reference of a mutable valuemother = 'Lily Evans'gryffindor = mother# Concat adds a string to the called stringmother.concat(' - Potter')puts gryffindor 
# => 'Lily Evans - Potter'
mother.object_id == gryffindor.object_id
# => true

Both mother and gryffindor point to the same string in memory and thus mutating the value using one variable affects both.

With reassignment however

mother = 'Ginny Weasley'puts gryffindor 
# => 'Lily Evans - Potter'
mother.object_id == gryffindor.object_id
# => false
  • Assigning the original to a new value creates a new value in memory — and the copy continues to point to the original value

Passing to a function

  • Immutable types are passed by value and mutable types are passed by reference
  • This isn’t technically correct. Ruby appears to behave this way — for immutable values it is actually passing by reference value. This is all you need to know though. If you want to know more — Launch School is a great resource on all things Ruby.
  • Object Passing in Ruby — by Reference or by Value?
# Mutable values #wandmaker = 'Garrick Ollivander'def add_house(name)  # Is this a copy made only for the execution of this method?  name.concat(' - Ravenclaw')  puts name  # memory address for name  puts name.object_idendadd_house(wandmaker)  # Testing whether original value was changed  puts wandmaker  puts wandmaker.object_idend
# Garrick Ollivander - Ravenclaw# 70349890968900# Garrick Ollivander - Ravenclaw# 70349890968900

The value for wandmaker was permanently modified outside of the method add_house and the object_id methods show that the memory address is the same inside and outside the method.

  • Ruby, for mutable values, is pass by-reference — an additional pointer is being created to the same place in memory. That value is being altered.

For reassignment however — the behavior is different

tonks = 'nymphadora tonks'def new_capitalize(name)  capital_name = name.capitalize  puts capital_name  puts capital_name.object_idendnew_capitalize(tonks)puts tonksputs tonks.object_id# Nymphadora tonks# 70314315512820# nymphadora tonks# 70314315512900

With reassignment — the original value remains the same and the memory addresses are different.

  • Reassignment creates a new place in memory. Modification changes the current place in memory.

JavaScript

In JavaScript — objects are mutable and only primitive types are immutable

There is no way to find the memory address of a value in JavaScript (that I have been able to find) but for primitives it appears to be copy-by-value and for objects by-reference

Copy by-value — primitive

// String is a primitive and thus immutablelet patronus_ron = 'Jack Russel Terrier';// Creating a copy by-valuelet patronus_dog = patronus_ron;// Concatenating a string to the originalpatronus_ron += ' + Otter';// Does not affect the copyconsole.log(patronus_dog) // 'Jack Russel Terrier'

Because primitive types are immutable - attempting to change the value seems to create a new place in memory rather than mutate the original

Copy by-reference — object

// Objects are mutable, copies are by-referencelet severus = {lastName: 'Snape', proffesion: 'Potions Master'};// Creating a 'copy' (additional pointer)let headmaster = severus;// Changing the originalseverus.patronus = 'doe';// Mutates the copyconsole.log(headmaster);// {"lastName":"Snape","proffesion":"Potions  Master","patronus":"doe"}
  • Both variables are pointers to the same object in memory — changing the value changes all references

Passing works the same way as copying

Primitive: by-value

// String type
yearsInAzkaban = 12;
function add(number) { number += 2; console.log(number);}add(yearsInAzkaban);// 14console.log(yearsInAzkaban);// 12

Object: by-reference

let deathEater = {name: 'Bellatrix Lestrange'};function addPureBlood(wizard) {  wizard.bloodStatus = 'Pure';  console.log(wizard);}addPureBlood(deathEater);console.log(deathEater);// Both the orginal and copy point to the same value// {name:"Bellatrix Lestrange", bloodStatus:"Pure"}

Ruby and JavaScript really aren’t too different when it comes to datatypes and mutability. If I missed anything or something was left unclear, please leave a comment below.

Thanks for reading! Take care.

Ricardo Ledesma

Written by

Software Developer. Enthusiastic carrot farmer.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade