This workshop is important because: Ruby is a powerful and popular language for server-side web development. It's the foundation for Ruby on Rails, one of the most prolific frameworks in the web. It's also a good introduction to a group of languages with a very different syntax.
After this workshop, developers will be able to:
- List Ruby data types.
- Leverage JavaScript experience to recognize patterns and structures in Ruby.
- Articulate strategies to learn new programming languages and frameworks.
- Run Ruby code in an interactive CLI or from a file.
Before this workshop, developers should already be able to:
- List JavaScript data types.
- Recognize and code JavaScript conditionals and loops.
As we learn Ruby, it's important to revisit how we learned our first language and use that to organize the study of our new language. Learning our second programming language is a process of translating concepts, expressions, and patterns from our familiar language into our new language.
Learning our first language involved more identification and comprehension of the knowledge required to implement our first programs. We should begin by organizing this knowledge to build a better understanding as we transition to Ruby.
Note: Why not count HTML and CSS? click to see more!
Neither HTML nor CSS is capable of handling complex calculations alone. We couldn't use them to implement a variety of algorithms. Formally, computer scientists would say these languages aren't Turing Complete. The bottom line is that even though HTML and CSS are programming languages, their concepts won't transfer as well to other languages.
- What is JavaScript? What does it look like?
- How did we build up to back-end web development from the fundamentals of JavaScript?
- What could possibly be different in another language? How could we change the syntax, but keep the most important structures?
"I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language."
- Ruby creator Yukihiro Matsumoto (a.k.a. "Matz")
One of the things that's important to people who write code in Ruby is how the code reads. Rubyists are known for writing code in a way that reads as much like normal English as possible. That helps make it easy to learn for beginners.
Check out this example:
def make_a_sentence(words)
words.join(' ') + "!"
end
make_a_sentence(['You', 'are', 'already', 'experts'])
# => "You are already experts!"
Without knowing anything about Ruby, you can probably guess how some of this works:
-
What kind of object is
make_a_sentence
? -
What does
def
do? -
What's the purpose of the line that starts with
#
?
You might notice something else interesting – where are the semicolons? You don't need them!
Ruby is lauded for being clean and beautiful - it has less punctuation and fewer reserved words than JavaScript! Over time, you'll find you have an appreciation for both languages, but for now let's relish forgetting the ;
!
# Comments
It's worth noting that while single-line comments in JS look like this:
// I'm a comment
Ruby's are like this:
# I'm a comment, too!
A "hash rocket" or "fat arrow" in a comment is a convention that means the comment shows a value that will get returned by a method or expression:
4 + 4
# => 8
Ruby and JavaScript are both interpreted languages, meaning there's another program on our computers that knows how to look at code in those languages and translate it into machine-readable code basically line by line as its run. Some ideas will carry over from JavaScript in a really straightforward way.
There are a lot of differences between the JavaScript and Ruby interpreters, though. A few important examples are that Ruby can't pass around functions, doesn't hoist variables, and has a different system for variable scope.
We'll see more about each of these differences later. For now, keep in mind that your intuition could mislead you - you should look at documentation and experiment as you learn Ruby.
We're going to use PRY, an interactive Ruby shell tool, so we can type some Ruby commands and see exactly what happens in real time.
Open up your terminal, and from anywhere, type gem install pry
, then type pry
. This will change your terminal tab into an interactive ruby console.
Other options for running ruby code:
-
Use
irb
(interactive ruby) in your terminal. -
Create a
.rb
file. Write your code that file, then run it withruby YOUR_FILE_NAME.rb
.
What are some data types you have used in JavaScript?
- Booleans are written as
true
andfalse
- Numbers are written as
12
or9.45
- Strings are written as
"awesome"
or'awesome'
- Special undefined type for things that have never had a value
- Arrays are written as
['x','y',3]
- Objects are written as
{key: 'value', thing: true, stuff: [1,2,3]}
, and have a special null
Now, let's experiment to see which of those are similar in Ruby, and which are different.
- Let's start with
undefined
. Typeundefined
intopry
and hit enter.
We get an error, so
undefined
isn't defined in Ruby. In fact, Ruby doesn't have an undefined type - we'll just get this same error message if Ruby doesn't know a value for a variable. Remember this error message!
- Try typing
true
orfalse
into pry. Are these defined in Ruby? How do you know?
click to review
We don't get an error, so these must be defined in Ruby. In fact, these are still our booleans!
Try typing
true.class
andfalse.class
to see the Ruby class for each:TrueClass
/FalseClass
!
- How about those numbers?! Check that they're defined, then try
3.class
and3.14.class
.
click to review
Two things to note:
- numbers with decimals are Floats
- Integers are divided into a few classes. Here we see
FixNum
. If you type in a really big number, you can seeBigNum
.
"hello world"
is still a String (you can check with"hello world".class
.
Try "hanging a dot" in
pry
(type"hello world"
, then hit tab a few times) to see the methods available for Ruby strings.
-
[1,2,3,4]
is still an Array. Hang a dot! -
{keys: ['some', 'values'] }
is called a Hash, but works almost the same as a JavaScript object.
One main difference is that values inside a Hash must be accessed with bracket notation (try it!).
- Ruby's version of
null
isnil
. What is its class?
You'll probably see this class in error messages as a sign that something isn't defined correctly.
- Ruby has an extra data type called a Symbol! A symbol is specified using a colon in front of a string of characters. For example
:hello
is a symbol in Ruby.
Symbols are like strings, except they only get stored in memory once. This means that they are less memory intensive, but they're also immutable (their value can't change). JavaScript recently adopted symbols. In both languages, they're often used as the keys inside objects/hashes.
Most importantly, in Ruby, everything is a reference data type. There are no primitives! That means that each of the above data types have methods & properties just like our JavaScript objects did.
- Booleans are written as
true
andfalse
- Integers are written like
12
- Floats are written like
9.45
- Strings are written like
"awesome"
- Symbols are written like
:awesome
- Arrays are written like
['x','y','z']
- Hashes are written like
{key: 'value', things: true, stuff: [1,2,3]}
or{:key => 'value'}
and accessed with bracket notation (myHash[:key]
) - nil is the equivalent of JavaScript's
null
Float on!
Unlike JavaScript, Ruby categorizes numbers as floats or integers. This creates some interesting results! Let's take a look in PRY:
- What happens if we use
pry
to calculate5 / 2
?
Have we broken Ruby? No, we have given ruby two integers (numbers with no decimal places), so ruby gives us an integer back.
- Compare to what happens when we divide an integer by a float, with
5 / 2.0
.
This is called "Type Coercion"; Ruby now knows that we want a float back.
- We've seen a similar result with JavaScript:
'1' + 4
=> '14'
What happens if you enter the code above into pry?
- Try
"rah"*3
and5*"yay"
. What happens? Experiment!
"7"
wonders what it's like to be a number
If we want to convert one data type to another in Ruby, there are some built-in methods that we can use. Here are a few examples:
# Converting to a String
3.14.to_s
=> "3.14"
# Converting to an Integer
"16".to_i
=> 16
-
Can you find at least one other example?
-
In JavaScript, we saw that
"7" == 7
istrue
but"7" === 7
isfalse
. What do you get when you try these out in pry?
Concatenate less.
Our strings have a superpower!
One super awesome trick that you will undoubtedly use all the time comes from our friend, the String object.
It's called string interpolation – and it lets us build complicated strings without having to add them together the old fashioned way. It's similar to template literals in JavaScript.
- Try out this code:
first = "Ben"
last = "Franklin"
first + " " + last # => Ben Franklin
- That works, but this is way cooler:
first = "Ben"
last = "Franklin"
"#{first} #{last}" # => Ben Franklin
So, so useful. More complex code can run in those brackets, and Ruby will evaluate it and use the results in the string, just like we want!
- But what are the limitations?? (Try out a few examples with single quotes.)
What do they mean?
We haven't seen symbols before.
- Try using Ruby's built in
.object_id
method to see the difference between symbols and strings:
"hi".object_id # => 70359038665560
"hi".object_id # => 70359036620120
:hi.object_id # => 1092828
:hi.object_id # => 1092828
- Why do you think symbols are used as the keys for hashes?
Just like JavaScript, we're gonna need some variables to hold stuff.
Unlike JavaScript, Ruby's variables don't need to be declared with a special reserved word.
Where you're now used to:
var webDeveloper = "me";
We can skip right to the good stuff:
web_developer = "me"
A local variable in Ruby is written in lower_snake_case
by convention.
favorite_food = "donuts"
favorite_food *= 3 # => "donutsdonutsdonuts"
We'll talk about Ruby scoping when we go over methods, but know that local variables are restricted to the method they're inside of. They can't get their value outside the method, and they are deleted once the method is finished.
Usually, we're able to change the value a variable's holding if we so choose – constants are designed for the opposite. Constants are meant to be placeholders that never change.
WAR_QUOTE = "War never changes."
WAR_QUOTE = "What is it good for?" # warning: already initialized constant
Constants are meant to be defined only once, so they're often used for things like storing application settings, or other stuff we don't intend to change.
JavaScript's newest version recently added constants with the
const
reserved word.
You'll see many other conventions of Ruby as you learn it!
The console.log
method is an awesome debugging tool in JavaScript. Ruby has three methods that all print out output: puts
, p
, and print
. Use pry to investigate the differences among these methods. Prepare to explain to the group.
Conditionals were an important part of JavaScript control flow; we use if/else if/else
all the time. What is the Ruby syntax for conditionals? Prepare an example of how you'd use conditionals in Ruby.
Repeated behavior means loops! JavaScript celebrated for
and while
, and we also had the iterator method Array.prototype.forEach
. Ruby has many more ways to loop. Take a look at:
-
.times
: What is a JavaScript equivalent? Can you give an example of when you would use this method to loop? -
.each
: What is a JavaScript equivalent? Can you give an example of when you would use this method to loop?
- What are some strategies you're using to pick up Ruby?
- What resources do you think will be helpful for you?