RUBY · STEP 1 · INTRO
Ruby · Intro to the language
Ruby 4.0 (any 3.2+ works): variables, input, conditionals, loops, arrays, hashes and methods — each shown first in the JavaScript you know, then in Ruby.
What you will learn#
- Creating Variables in a New Language
- Conditionals in a New Language
- Looping in a New Language
- Collections in a New Language
- Writing Functions in a New Language
Getting Started#
Install the current Ruby from ruby-lang.org/en/downloads (4.0 as of this writing; anything from 3.2 up runs everything on this page and is what Rails 8.1 requires). Most people install it through a version manager — the Install Ruby on Rails guide walks through that on macOS, Ubuntu and Windows (WSL). Then open a terminal:
ruby --versionirbirb is Ruby's REPL: type an expression, press Enter, see the result; exit leaves. To run a file: ruby hello.rb.
Creating Variables#
How we did it in Javascript
// We create constant variables with the const keywordconst myConstant = 5// We create re-assignable variables with the let keywordlet myVariable = "Hello World" // We print variables to the console using console.logconsole.log(myConstant)console.log(myVariable)How we do this in Ruby
# A name that starts with a capital letter is a constant. Ruby warns you if you reassign it# (it does not stop you); the convention for values is SCREAMING_SNAKE_CASEMY_CONSTANT = 5# Everything else is a plain variable and re-assignable; snake_case is the normmy_variable = "Hello World" # puts prints a value followed by a newline; parentheses are optional, puts(MY_CONSTANT) is the same callputs MY_CONSTANT# p prints the value's "inspect" form (strings keep their quotes) and returns it; handy for debuggingp my_variableReceiving Input#
In the browser, input comes from forms or prompt. In Node, reading from the terminal goes through the readline module:
// Node: ask a question in the terminal and wait for the answerimport readline from "node:readline/promises"import { stdin as input, stdout as output } from "node:process" const rl = readline.createInterface({ input, output })const name = await rl.question("Who are you? ")console.log(`Hey there ${name}!`)rl.close()How would we do that in Ruby?
# puts prints the question; gets reads one line from the terminal, including the newline the Enter key addsputs "Who are you?"user_input = gets.chomp # chomp removes that trailing newline # #{} interpolates any Ruby expression into a double-quoted stringputs "Hey there #{user_input}!"gets always returns a string (gets.chomp.to_i for a number), and interpolation only works inside double quotes.
Conditionals#
If statements in Javascript
const num = 5 if (num > 3){ console.log("num is greater than 3")} else if (num > 1){ console.log("num is greater than 1")} else { console.log("num is 1 or less")}If statements in Ruby
num = 5 # No parentheses or braces: the condition ends the line, and one `end` closes the whole ifif num > 3 puts "num is greater than 3"elsif num > 1 puts "num is greater than 1"else puts "num is 1 or less"endThings to know: the middle branch is spelled elsif; &&, ||, ! work as in JavaScript; == never coerces types, so there is no === to reach for; and only nil and false are falsy — 0 and "" are truthy. You'll also see unless (an inverted if) and the one-line form puts "big" if num > 3.
While Loops#
In Javascript
let counter = 0 //This will loop 10 timeswhile(counter < 10){ console.log(counter) counter += 1}In Ruby
counter = 0 # this will loop 10 times (Ruby has no ++, use += 1)while counter < 10 puts counter counter += 1endwhile is rare in day-to-day Ruby. You will mostly loop by handing a block ({ } or do ... end) to a method, which calls it once per item:
10.times { |counter| puts counter } # 0 to 9[1, 2, 3].each { |item| puts item }10 Minute Exercise#
Write the code to do the following:
- Loop 10 times starting the counter at 0
- On each loop if the counter is even print "it's even"
- If odd, print "meow" if the number is divisible by 3
- Otherwise print nothing
Collections#
In Javascript we have arrays and objects
const myArray = [1,2,3] console.log(myArray) //logging the entire arrayconsole.log(myArray[0]) // logging an individual item const myObject = { cheese: "gouda", bread: "rye"} console.log(myObject) //logging the entire objectconsole.log(myObject.cheese) // logging a property using dot notationconsole.log(myObject["bread"]) // logging a property using square bracket notationIn Ruby you have arrays and hashes
my_array = [1, 2, 3]puts my_array # puts prints each element on its own linep my_array # p shows the array the way you would type it: [1, 2, 3]p my_array[0] # an individual itemp my_array[-1] # negative indexes count from the end my_hash = { cheese: "gouda", bread: "rye" }p my_hash # {cheese: "gouda", bread: "rye"}p my_hash[:cheese] # one value, looked up by its keyp my_hash[:jam] # a missing key gives nil, not an error:cheese is a symbol — a lightweight, immutable name Ruby uses for identifiers; cheese: inside { } is shorthand for :cheese =>. The classic gotcha: my_hash["cheese"] is a different key from my_hash[:cheese] and returns nil. There is no dot access for hash keys.
10 Minute Exercise#
Look up Ruby's Array methods and apply them to the following list.
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]- How to find an array's length (
length/size) - How to loop over an array (
each,each_with_index,map) - How to add and remove items from an array (
pushor<<,pop,unshift,shift,delete,delete_at)
Functions#
in Javascript
const addNums = (x, y) => { return x + y} console.log(addNums(5,5))In Ruby
# def ... end defines a method; the value of the last expression is returned automaticallydef add_nums(x, y) x + yend puts add_nums(5, 5)return exists, but Ruby only writes it to leave a method early; the last line is the return value. Keyword arguments with defaults are built in:
def greet(name, greeting: "Hello") "#{greeting}, #{name}!"end puts greet("Arthur") # Hello, Arthur!puts greet("Arthur", greeting: "Welcome") # Welcome, Arthur!The closest thing to an arrow function is a lambda, add = ->(x, y) { x + y }, called with add.call(5, 5); mostly you'll meet anonymous functions as the blocks passed to each, map and select.
10 minute exercise#
Write the following functions
sub_numsthat takes two arguments and returns their differencesay_hellothat takes a name as an argument and says hello to that namesay_hello_advthat takes a hash withnameandagekeys and prints "hello {name}, how does it feel to be {age} years old"loopertakes one array as an argument, loops over the array and prints each item individually
Resources to Learn More#
- Control expressions —
if/elsif/unless,while,caseand the modifier forms, from the official syntax reference - Methods —
def, default values, keyword arguments, blocks - Kernel —
puts,p,print,getsand the other methods available everywhere - Array and Hash — the methods the exercises ask you to find
- Official Ruby documentation — the index of everything above, plus Ruby's own tutorials
See also