- Compare/contrast Ruby and Javascript as programming languages.
- Run Ruby code by REPL (Pry/Irb) and file.
- Identify specific differences between Ruby and Javascript in the following areas...
- Syntax
- Variables
- Fundamental Data Types
- Data Collections
- Conditionals
- Methods (Functions)
- Data Immutability
- Examine Ruby symbols and data immutability.
- List three useful methods for arrays and hashes.
Ruby is a server-side programming language.
Ruby resides in and is processed by a webpage's server.
- What is a server?
- It gathers information from the database, filters it using logic and from that generates something to send back to the user. That could be HTML or, in the case of an API, JSON.
- That means you cannot look at or mess with a site's server-side code as you did with Javascript via the browser console.
- We won't be including Ruby files in our HTML documents. You'll learn more about back-end development and how to connect everything together next week.
- "Matz Is Nice And So We Are Nice"
- Mentality not only applies to how you should treat your fellow developers, but also the philosophy behind Ruby itself.
- Yukihiro Matsumoto ("Matz") created Ruby to increase developer happiness.
"Programmers often feel joy when they can concentrate on the creative side of programming, so Ruby is designed to make programmers happy." โ Yukihiro "Matz" Matsumoto
While it isn't exactly simple, a lot of its features are going to feel intuitive.
"Ruby is simple in appearance, but is very complex inside, just like our human body." โ Yukihiro "Matz" Matsumoto
We will be running Ruby code via the Terminal in two different ways. But first, let's make sure you're all set up...
Check to make sure you have Ruby installed: $ ruby -v
- Should get back something like:
ruby 2.2.1p85 (2015-02-26 revision 49769) [x86_64-darwin14]
- If you need to install:
$ rvm install 2.2
$ touch app.rb # Create a Ruby file
$ ruby file_name.rb # Run that ruby file
This is the equivalent of running
node script.js
in the Terminal.
Just like Javascript and the browser console, we can use tools like Pry and IRB to run Ruby in a REPL.
- Install:
$ gem install pry
- Run REPL:
$ pry
- Quit from REPL:
exit
- Alternative:
$ irb
A
gem
is a tool or application written in Ruby. We install them by entering$ gem install gem_name
in the Terminal. Explore rubygems.org if you're interested in learning more.
With a partner, write down some differences in syntax, "nice" or otherwise, you noticed between Ruby and Javascript?
No longer need to precede new variables with var
, let
, or const
. Just use the name of the variable!
- Variables are instantiated as they are used.
- Written in
snake_case
. That means all lower case with words separated by underscores. - You should still keep names semantic!
Variables are still assigned using a single equals sign ( =
)
my_favorite_animal = "flying squirrel"
# => "flying squirrel"
Although we don't use var
, let
, or const
, there is still syntax to designate whether a variable is local or global.
$
makes it global (e.g.,$my_number
)- Undesignated implies
local
(e.g.,my_number
) - All-caps makes it a constant. That is, Ruby will give you warnings if you try to change the value. (e.g.,
PI = 3.14
)
While your code will work if you close a line with ;
, common practice is not to use them.
Since I'm in a Javascript state of mind, you will notice me using them pretty often.
number = 3
# => 3
if( number == 3 ) # with parens
puts( "It's a 3!" )
end
# It's a 3!
# => nil
if number == 3 # without parens
puts "It's a 3!"
end
# It's a 3!
# => nil
puts
is the equivalent of Javascript's console.log()
.
puts "Hello, Ruby!"
# Hello, Ruby!
# => nil
Ruby also allows us to easily accept inputs from the command line using gets
.
user_input = gets
# => "My input\n" (Note that this line was typed by the user in the terminal)
user_input
# => "My input\n"
Some notes about gets
...
- Usually
gets
is followed by.chomp
, which removes the new line generated by the user hitting return. - If you need to convert your value to a number, add
.to_i
to the end of the method.
Let's test gets
by using it in a .rb file...
# Run this code in app.rb
# Asks for and stores a command line input into the variable as a string.
puts "How old are you?: "
user_input = gets.chomp.to_i
if user_input > 10
puts "You are older than ten"
end
# In the terminal from in the same directory as app.rb
$ ruby app.rb
How old are you?:
20
You are older than ten
$ ruby app.rb
How old are you?:
8
Spend 15 minutes reading through everything up until Data Types Exercises.
- While we could re-teach you what numbers, strings, conditionals, etc. are like in Ruby, you know enough about programming languages from your experience with Javascript to pick up on this information yourself pretty quickly.
- Because of this, the peculiarities of Ruby will be apparent. These are the things you need to be aware of in the next few classes.
Everything in Ruby is an object.
- By "object" we mean that everything has its own set of properties and methods.
- Not a new concept. Some data types in Javascript had their own properties and methods (e.g.,
string.length
). - You will learn more about this when you dive into Ruby OOP...
Ruby uses the same arithmetic operators as Javascript
+
,-
,*
,/
,%
- Same order of operations too: P.E.M.D.A.S.
1 + 2 # Addition
# => 3
6 - 5 # Subtraction
# => 1
5 * 2 # Multiplication
# => 10
30 / 5 # Division
# => 6
31 / 5 # Note: integer division
# => 6
30 % 5 # Modulo (remainder)
# => 0
31 % 5
# => 1
3 ** 2 # Exponentiation
# => 9
Notice the use of
**
to perform exponential operations in Ruby. We don't have this shortcut in Javascript.
Words, just like in Javascript.
- Surrounded by single or double-quotes
- Ruby uses similar escape characters
- List
- Must instantiate string with double-quotes for escape characters to work.
name = "John"
# => "John"
full_name = "John\nDoe"
# => "John\nDoe"
puts full_name
# John
# Doe
# => nil
Not only can you concatenate strings, now you can multiply them too! Remember we couldn't do that in Javascript?
# Concatenation
"Hello " + "there!"
# => "Hello there!"
# Multiplication
"Hello there! " * 3
# => "Hello there! Hello there! Hello there! "
Sometimes you will want to print out a string that incorporates a variable. For example...
my_name = "Goku"
# => "Goku"
puts "Hi my name is: " + my_name
# Hi my name is: Goku
# => nil
This works fine. Things aren't so simple when that variable is of a different data type. Like a number...
min_power_level = 9000
# => 9000
puts "My power level is over " + min_power_level
# TypeError: no implicit conversion of Fixnum into String from (pry):4:in `+'
In cases like the above, you either need to convert the variable to a string using .to_s
or use something called "interpolation."
- Surround the non-string variable with a hashtag and curly brackets:
#{variable}
. Note: If you choose this option, you must use double quotes otherwise the interpolation will not work. - No Javascript equivalent (until ES6 came along!).
min_power_level = 9000
# => 9000
puts "My power level is over #{min_power_level}"
# My power level is over 9000
# => nil
Still true
and false
.
- We'll be using them in conditionals and comparisons just like in Javascript.
Comparison operators in Ruby are nearly identical to Javascript. However, the check for equality is always for both value and data type.
<
,>
,<=
,>=
,==
,!=
Don't worry about
===
in Ruby for now. It does not have the same application as in Javascript.
Logical operators are also similar.
!
,&&
,||
"Truthiness" and "falsiness" are a lot less complicated in Ruby.
- The only falsey values in Ruby are
nil
andfalse
.
Ruby's "nothing".
- The equivalent of Javascript's
null
. - You will usually see it when something does not have a return value (e.g., a
puts
statement). - Like in Javascript,
nil
is falsey.
Need to check if something is nil
? Use .nil?
NOTE: Any method that ends with a
?
means it will return a boolean value.
something = "A thing"
# => "A thing"
something.nil?
# => false
something = nil
# => nil
something.nil?
# => true
Complete the first set of exercises in this repo.
If you finish this section early, feel free to try out one of the Additional Exercises located at the bottom of the lesson plan.
Let's talk about variables and memory allocation in Ruby.
Haha!
Why is that so funny? Because variables are pointers to values in memory.
We can use the .object_id
method to demonstrate that two variables are pointing to the same object.
- Returns an integer identifier for the object that is automatically generated by Ruby.
Lets use
.object_id
to demonstrate that the above diagram is true.
a = "hi there"
# => "hi there"
b = a
# => "hi there"
a.object_id
# => 70295613250200
b.object_id
# => 70295613250200
a = "not here"
# => "not here"
a.object_id
# => 70295609398280
b.object_id
# => 70295613250200
All of the Ruby data types we have discussed so far are mutable.
- We can not only change what variables are pointing to in memory, but we can directly modify those values stored in memory as well.
Methods with an !
attached to the end of them usually mean that they will modify the value in memory they are being called on.
- Things can get tricky when you have multiple variables pointing at the same value. For example...
a = "veggie burger"
# => "veggie burger"
b = a
# => "veggie burger"
b.upcase!
# => "VEGGIE BURGER"
a
# => "VEGGIE BURGER"
Symbols are immutable values. That means they contain the same value through the entirety of a program and cannot be changed.
- Kind of like a string that never changes.
- Syntax:
variable_name = :symbol_name
- No Javascript equivalent (until ES6 came along!)).
favorite_animal = :dog
# => :dog
favorite_animal.upcase!
# NoMethodError: undefined method `upcase!' for :dog:Symbol
When/why would you use symbols?
- Most common use is as keys in hashes (the Ruby equivalent of objects -- more on that later).
- Make sure values that need to be constant stay constant.
- Enhance performance. Use less memory.
Pretty similar to Javascript, with some differences.
- No parentheses or curly brackets required.
- Begin blocks using
if
,elsif
(no second "e"!) andelse
- We close the whole loop using
end
.- This will be used throughout Ruby when dealing with code blocks (e.g., method/function).
Here's an example where we check for height at a roller coaster...
# In app.rb
puts "Welcome to the Iron Rattler! How tall are you (in feet)?"
height = gets.chomp.to_i
if height < 4
puts "Sorry, you'll fly out of your seat if we let you on."
elsif height < 7
puts "All aboard!"
else
puts "If you value your head, you should not get on this ride."
end
Spend 10 minutes reading everything up until Data Collections Exercises.
An ordered collection of related values. Same syntax as Javascript arrays.
- Square brackets.
- Values separated by commas.
- Zero-indexed.
numbers = [ 1, 2, 3 ]
# => [1, 2, 3]
animals = [ "dog", "cat", "horse" ]
# => ["dog", "cat", "horse"]
animals[0]
# => "dog"
animals[1] = "elephant"
# => "elephant"
animals
# => ["dog", "elephant", "horse"]
Another super cool Ruby feature is that you can perform arithmetic operations -- addition, subtraction, multiplication -- on arrays!
numbers = [ 1, 2, 3 ]
# => [1, 2, 3]
more_numbers = [ 4, 5, 6, ]
# => [4, 5, 6]
lots_of_numbers = numbers + more_numbers
# => [1, 2, 3, 4, 5, 6]
lots_of_numbers - [ 4, 5, 6 ]
# => [1, 2, 3]
numbers * 3
# => [1, 2, 3, 1, 2, 3, 1, 2, 3]
Ruby is very nice. It provides us with an extensive library of array methods we can use to traverse and manipulate arrays.
- Documentation
- Can't go over them all, but chances are if you could do it in Javascript then you can do it in Ruby.
IMPORTANT: You DO NOT need to memorize these. The following is just a sample of array methods available to you. You'll come to be more familiar with these as you need them and look them up in documentation.
tl;dr: The more you Google them, the better you'll remember them.
These Javascript methods also exist in Ruby and are used the same way.
numbers = [ 1, 2, 3, 4, 5 ]
# => [1, 2, 3, 4, 5]
numbers.push( 6 )
# => [1, 2, 3, 4, 5, 6]
numbers.push( 7, 8, 9 )
# => [1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers.pop
# => 9
numbers
# => [1, 2, 3, 4, 5, 6, 7, 8]
- Organizes array values from lowest to highest. Numbers and strings.
numbers = [ 3, 1, 5, 2, 4 ]
# => [3, 1, 5, 2, 4]
numbers.sort
# => [1, 2, 3, 4, 5]
- Removes an argument from an array.
- If there are multiple instances of that argument, it will delete them all.
- Look up:
.delete_at()
,.slice()
numbers = [ 3, 1, 2, 2, 4 ]
# => [3, 1, 2, 2, 4]
numbers.delete( 2 )
# => 2
numbers
# => [3, 1, 4]
There are a ton of array methods available to us in Ruby. Explore them using the Ruby documentation.
A unordered, "dictionary-like" collection organized by key-value pairs. Very similar to Javascript objects...
wdi_class = {
teacher: "Keane",
students: [ "Blossom", "Bubbles", "Buttercup" ],
classroom: 423,
in_session: true,
schedule: {
morning: "Intro to Ruby",
afternoon: "Ruby Enumerables"
}
}
# => {:teacher=>"Keane", :students=>["Blossom", "Bubbles", "Buttercup"], :classroom=>423, :in_session=>true, :schedule=>{:morning=>"Intro to Ruby", :afternoon=>"Ruby Enumerables"}}
Accessing hash values...
wdi_class[:teacher]
# => "Keane"
Modifying hash values...
wdi_class[:teacher] = "Mojo Jojo"
# => "Mojo Jojo"
You can also use strings as hash keys.
wdi_class = {
"teacher" => "Keane",
"students" => [ "Blossom", "Bubbles", "Buttercup" ],
"classroom" => 423,
"in_session" => true,
"schedule" => {
"morning" => "Intro to Ruby",
"afternoon" => "Ruby Enumerables"
}
}
Then can access in this way...
wdi_class["teacher"]
# => "Keane"
And modify...
wdi_class["teacher"] = "Mojo Jojo"
# => "Mojo Jojo"
Note the use of
=>
(or "hash rockets") instead of:
when using strings as keys.
Like arrays, Ruby also provides us with a library of hash methods.
As mentioned with arrays, do not worry about memorizing these methods. Just know how to look them up should the need arise.
Returns an array with all the keys in a hash.
wdi_class.keys
# => [:teacher, :students, :classroom, :in_session, :schedule]
Combines two hashes. If both of your hashes have the same key, the one in the hash you set as the argument in the parameters will take precedence.
classroom = {
room: 1
}
# => {:room=>1}
locations = {
location_one: "Providence",
location_two: "Boston",
location_three: "DC"
}
# => {:location_one=>"Providence", :location_two=>"Boston", :location_three=>"DC"}
silly_hash = classroom.merge( locations )
# => {:room=>1, :location_one=>"Providence", :location_two=>"Boston", :location_three=>"DC"}
classroom
# => {:room=>1}
locations
# => {:location_one=>"Providence", :location_two=>"Boston", :location_three=>"DC"}
silly_hash
# => {:room=>1, :location_one=>"Providence", :location_two=>"Boston", :location_three=>"DC"}
Use ranges to quickly generate arrays of data types.
- Parentheses.
- Min and max value, separated by two periods.
- Generate array using
.to_a
method.
(1..5).to_a
# => [1, 2, 3, 4, 5]
("a".."z").to_a
# => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
Complete the second set of exercises in this repo.
If you finish this section early, feel free to try out one of the Additional Exercises located at the bottom of the lesson plan.
- As stated before, everything in Ruby is an object so there is no distinction in this language between functions and methods. Under the hood, even seemingly stand-alone functions are in fact associated with an object. The convention, however, is to call these methods.
Components
def
- the Ruby equivalent offunction
double
- the method name in the below examplenumber
- the argument name in the below exampleend
- closes the method
def double( number )
doubled_number = number * 2
return doubled_number
end
double( 3 )
# => 6
double 4
# => 8
You may have noticed that we use the same return
notation as Javascript. This is called an explicit return, because we identify what exactly we want returned from the function.
Ruby also lets us make implicit returns. This means that when we do not use the return
keyword, Ruby will automatically return the value of the last line of code in the method.
- We encourage you to use explicit returns so we know exactly what your method is returning.
def double( number )
doubled_number = number * 2
doubled_number
end
# => :double
double( 3 )
# => 6
double 4
# => 8
Ruby methods can also establish default argument values.
- In the below example, if we do not provide our
double
method with an argument, it will default to 5.
def double( number=5 )
doubled_number = number * 2
puts "Your doubled number is #{doubled_number}"
doubled_number
end
# => :double
double
# Your doubled number is 10
# => 10
- What are Ruby's 5 main data types?
- Describe the difference between what is truthy/falsey in Ruby vs JavaScript?
- What's the difference between explicit and implicit return?
- How would you add a key / value pair to an existing hash?
- How many values can a method return? Which methods don't return anything?
- GA DC Lesson
- Learn X in Y minutes: Ruby
- Code School: Ruby (Ruby Bits 1 and 2)
- Ruby Monk
- Why's Poignant Guide to Ruby
- Ruby Koans
- Screencasts