22
Ruby Basics
Hello, dear devs. 👋
I am back, bringing to you (again) the weirdest articles on the internet. I am sure you were waiting for that, right? (Please don't answer!)
Today, as the title points out, I will be briefly talking writing about the Ruby language and some of its features. 😉
If you have read my previous posts (something I don't recommend) I usually write about JavaScript related stuff and I love doing so.
But today I have decided to vary a little bit and talk about Ruby that is an extremely powerful language and, long story short, thanks to it I am a developer today. (Am I? 🤔)
Short answer: no. Indeed, it has been losing "popularity" along the years I cannot deny that but it is way far from death.
The Clash is my favorite band ever, it also has been losing its popularity but can you tell they are dying? 🎸 Yeah, you just cannot! (In musical terms, I meant.)
I am losing focus here, sorry. 😅
Ruby just got a recent minor update to 3.0.2
on July 7th but it is beyond the current scope of this article.
Paraphrasing someone I have no idea:
"... Knowledge does not occupy space!"
There are many discussions about this specific subject out there but honestly, I am here to bring you the basics of Ruby so let's get started because life is short.
Given the language vastness it is impossible to include here, in a mere 10 minutes reading post, either all its features, different ways of doing the same thing or even best practices. I hope you understand that.
The examples are based in both my mental disorders, personal delirium and confused state of mind caused by unknown reasons, according to my psychologist.
If you are OK with that, welcome aboard !, otherwise you are free to go. There are tons of normal people waiting for you somewhere else. 😂 🤣
🚨 The next three paragraphs I didn't write myself. They are, in my vision, plausible to explain what I have in mind. I am not a huge fan of "reinvent the wheel". 🚨
Ruby is a dynamic, interpreted, high-level and general-purpose programming language. Wikipedia:
It was was created by Yukihiro Matsumoto (Matz), in Japan in the mid 1990's and was designed for programmer productivity with the idea that programming should be fun for programmers.
It emphasizes the necessity for software to be understood by humans first and computers second. Launch School:
Please pay special attention for those three sentences:
"... necessity for software to be understood by humans first (🙋🥇) and computers second (🗣️ losers!)."
" ... It was was created by Yukihiro Matsumoto (Matz), in Japan."
" ... with the idea that programming should be fun for programmers."
Quote 1: Most of the time, Ruby statements are very similar to plain English and it turns out a language very easy to read and understand by us, mere mortals.
Quote 2: Try to convince me about something bad that is originally from Japan and fail miserably.
👉 [ Suggest a gif (about Japan) in the comments section and I will upload the best here. ]. 👈
Thanks for participating, Juan. The gif
below is in your honor! 🤜🤛
Quote 3: The 'having fun' part you are going to discover very soon. If you stick with me until the end, of course. 😊
If you would like to follow along and don't have Ruby installed in your machine, don't worry. Install it! 🤣 😆 😂
Just kidding, you can use the Ruby Online Compiler & Interpreter - Replit. It is a mixing of the irb
console and an IDE
in the same page.
IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby expressions ...
Module: IRB
You can comment a block of code, for example, using both the =begin
and =end
keywords and placing the block to be comment between them.
=begin
Dale a tu cuerpo alegria Macarena
Eeeh Macarena ....
Aaahe!
=end
You can also have an one-line comment using the #
.
# Never gonna give you up, never gonna let you down ...
Both functions are used to display output on the screen. The major difference between them is that puts
inserts a newline at the end.
print "Hello, "
print "darkness my old friend."
# Result:
# Hello, darkness my old friend
puts "Hark, hark! I hear"
puts "The strain of strutting chanticleer"
puts "Cry, Cock-a-diddle-dow!"
# Result:
=begin
Hark, hark! I hear
The strain of strutting chanticleer
Cry, Cock-a-diddle-dow!
=end
Ruby has four different kinds of variables
where which one is declared in its specific way:
local = "Hey, I am a local variable."
_other_local_var = "Never mess up with a local!"
@instance = "For instance, I am an instance variable."
@@class = "I am 'classy'."
$global = "Globalization rules!"
Ruby has several data types: String
, Integer
, Float
, Boolean
(TrueClass
, FalseClass
), Symbol
and Nil
(NilClass
).
I wouldn't classify them as primitive data types because everything is Ruby is an object. (or almost everything. Keep reading! 😜)
$my_name = "Clancy Gilroy"
puts $my_name.class # String
name = "X Æ A-12"
puts name.class # String
age = 35
puts age.class # Integer
gpa = 3.22
puts gpa.class # Float
had_fun = true
puts had_fun.class # TrueClass
is_hot = false
puts is_hot.class # FalseClass
week_points = nil
puts week_points.class # NilClass (absence of value)
symbol = :hello
puts symbol.class # Symbol
Did you notice the .class
method ? Since Ruby is a Fully Object Oriented language everything is an object
, a property of
or a method call on
an object.
By the way and being shallow, an object is the instance of a given class.
Think of a class
like a blueprint for creating objects, which determines initial values, attributes, behavior etc.
You can confirm the "almost everything is an object" theory using the .superclass
method.
puts TrueClass.superclass # Object
puts Integer.superclass # Object
puts String.superclass # Object
puts Object.superclass # BasicObject
# so on and so forth
Ruby has many built-in methods to manipulate strings.
Do you remember when I had mentioned that in Ruby things are similar to plain English? I bet you can guess what most of these methods below do, am I right? 😃
phrase = " Sometimes I’m confused by what I think is really obvious. But what I think is really obvious obviously isn’t obvious. "
puts phrase.upcase
puts phrase.downcase
# hint: .strip removes the empty spaces from both beginning and ending.
puts phrase.strip
puts phrase.length
puts phrase.include? "Some"
puts phrase.include? "Sure"
puts phrase.index("confused")
puts "auckland".capitalize
It is also possible to create both interpolation and concatenation of strings
.
character_age = "17"
character_name = "Link"
# Interpolation
puts "There once was a young man named #{character_name}"
# Concatenation ➕
# '.to_s' is the short method name for 'to string'
# There is more like '.to_i', '.to_f', '.to_a' etc
puts "he was " + character_age.to_s + " years old"
puts 5 + 9 # addition
puts 2 - 9 # subtraction
puts 6 * 9 # multiplication
puts 10 / 7.0 # division
puts 2 ** 3 # exponentiation
puts 3 % 2 # modulo or remainder
num = -163.23
num2 = 45.47
# returns the absolute number
puts num.abs # 163.23
# return a value rounded to the nearest value with "n" digits decimal digits precision.
puts num2.round # 45
# returns the ceil value
puts num2.ceil # 46
# returns the floor value
puts num2.floor # 45
# returns the square root of a given number (5.0)
puts Math.sqrt(25) # 5.0
# returns the natural logarithm (base e) or logarithm to the specified base of a given number, e.g. Math.log(x, base).
puts Math.log(100) # 4.605170185988092
Ruby arrays are collections of ordered, integer-indexed objects which can store numbers, strings, hashes, symbols, objects or even any other arrays.
# different ways to declare an array
friends = Array["Rapha", "Alexandre", "Andre", "Bogus"]
# I prefer this one 👇
fruits_array = ["cherimoya", "durian", "lamut", "langsat" ]
# What the heck? 🤢
hello = Array.new(5, "awful").to_s
# output: ["awful", "awful", "awful", "awful", "awful"]
puts hello
# Remind: Ruby Arrays indexing starts at 0.
puts friends[0] # Rapha
puts friends[-1] # Bogus
puts friends[0,2] # Rapha Alexandre
# Replacing items
friends[0] = "Fael"
# output: ["Fael", "Alexandre", "Andre", "Bogus"]
puts friends.to_s
puts friends.length # 4
# Down here the methods syntax are pretty much understandable
puts friends.include?("Fael")
puts friends.reverse
puts friends.sort
puts friends.empty?
puts fruits_array.push("rambutan")
## the example above (`push`) could also be done as shown below
fruits_array << "akebi"
The Ruby arrays built-in methods are not limited to just those ones I have mentioned above.
If you are eager to learn more (I am sure you are 🤓), Ruby docs is a really good resource to do so.
Ruby hashes are collections of key-value pairs, for example:
random_hash = {
:sao_paulo => "SP",
"rio_de_janeiro" => "RJ",
1 => "NY",
}
Remember that the way you declare the key
is the same you will use in order to successfully access its value
in a hash.
For example, trying to access random_hash["sao_paulo"]
would return nothing because :sao_paulo
is not the same as "sao_paulo"
. (Symbol
x String
)
puts random_hash
puts random_hash[:sao_paulo] # SP
puts random_hash["rio_de_janeiro"] # RJ
puts random_hash[1] # NY
puts random_hash.nil? # false
puts random_hash.length # 3
Ruby methods are used to tie or wrap together one or more repeatable statements into a single unit.
Along the article we have already used many methods, for example, length
, sqrt
, to_s
etc.
Someone, probably Matz, have already written them for us and for this reason they are the so called built-in.
Even Ruby being an amazing language it is practically impossible to include every single method that we would use in our daily life. We are free to implement them by our own.
Hint: Method names should begin with a lowercase letter.
"... If you begin a method name with an uppercase letter, Ruby might think that it is a constant and hence can parse the call incorrectly. "
Source: Tutorials Point
# Method without parameter(s)
# This is how you declare a method
def say_konnichiwa
puts "こんにちは"
end
# This is how you invoke it
say_konnichiwa
# Method with parameter(s)
def say_tadaima(title, name="Unknown")
puts "ただいま, #{title} #{name}!"
end
say_tadaima("Mr.", "Toguro") # prints "ただいま, Mr. Toguro!"
Note that the second parameter name
holds the default value Unknown
. In other words, if we call the same method without providing the second argument, the default value will be put in place. Example below:
say_tadaima("Mr.") # prints "ただいま, Mr. Unknown!"
We can also return
values from inside of our methods both explicitly or implicitly.
- Explicit return
:
def cube(num)
return num * num * num, 70, "return", true, "?????"
# Never reached
puts "No value after the return statement is reached"
end
# IT will console the result of "num * num * num"
puts cube(3)
# Prints the number "70"
puts cube(3)[1]
# Prints the string "return" and so on
puts cube(3)[2]
- Implicit return
:
def always_return
"I am always returned"
end
# Variable created for the sake of demonstration
result = always_return
puts result # "I am always returned"
In other words, methods are most likely those relatives we don't like. They always return. (🥁 Tu dum tsss)
is_dev = true
language = "Cobol"
if(is_dev && language == "Cobol")
puts "DISPLAY 'Hello, Cobol'."
elsif (is_dev && language == "Pascal")
puts "writeln('Hello, Pascal!');"
elsif (is_dev && language == "Delphi")
puts "ShowMessage('Hello Delphi');"
else
puts "👋"
end
We can also use comparisons inside of if / else
statements.
def max_number(num1, num2, num3)
if (num1 >= num2 and num1 >= num3)
return num1
elsif (num2 >= num1 and num2 >= num3)
return num2
else
return num3
end
end
puts max_number(9, 53, 77)
There is no mystery here. I am sure you can read this masterpiece of code and guess what it does.
def get_day_name(day_abbreviaton)
day_name = ""
case day_abbreviaton.downcase
when "ma"
day_name = "Maanantai"
when "ti"
day_name = "Tiistai"
when "ke"
day_name = "Keskiviikko"
when "to"
day_name = "Torstai"
when "pe"
day_name = "Perjantai"
when "la"
day_name = "Lauantai"
when "sun"
day_name = "Sunnuntai"
else
day_name = "En tiedä!"
end
# Implicit returns the value
day_name
end
puts get_day_name("ma") # Maanantai
puts get_day_name("koira") # En tiedä!
lucky_num = 70
# Note that the 'not' keyword is similar to '!=' (negation)
while not lucky_num == 77
puts "No Lucky #{lucky_num}"
lucky_num +=1
end
# You already know what is an array :)
people = ["C. Falcon", "Fox", "DK", "Ness", "Samus"]
# It will display all names in a different line
for person in people
puts person
end
# Same same but ... same
people.each do |person|
puts person
end
# Display numbers from range 0 to 5 (inclusive ..)
for inclusive in 0..5
puts inclusive
end
# Display number from range 0 to 4 (exclusive ...)
for exclusive in 0...5
puts exclusive
end
# Let's agree: This is plain English
# PS.: counting starts from 0
6.times do |phrase|
puts "Counting: #{phrase}"
end
This is my favorite part. Why? Because I remember when I have had my first contact with OOP (back in 2000's [btw, old are your ancestors 😠]) in Java
.
I was like: "What the heck is going on here?".
I got to understand it better because of the Ruby way of doing things.
## This is a very simple class
class Character
attr_accessor :name, :role, :home
end
## This is a very simple way to create a new object
character = Character.new()
character.name = "Rygar"
character.role = "Searcher"
character.home = "Black Mountains"
puts character.name
Good that you asked (🔮), under the hood the attr_...
creates the so famous getters
and setters
for you, for instance:
-attr_accessor
: creates the getter
and setter
methods.
-attr_reader
: creates only the getter
method.
-attr_writer
: creates only the setter
method.
TLDR;
# In other words this
attr_acessor :name
# Is the equivalent of
def name
@name
end
def name=(value)
@name = value
end
# Note: The equals sign is a Ruby convention when creating setters.
# Omitting it is considering a bad practice but still works.
# (if it is working don't touch! 👍)
Cool, right? We have achieved so much just writing very few lines of code. I have to confess, when writing code using Ruby sometimes I feel like cheating.
But, in my opinion, Ruby saves our time so we can worry about stuff that really matters.
Let's check an other manner to create a class
in Ruby.
class Shoes
attr_accessor :brand, :size, :color
# Allows you to set the initial values for a given object
# Does 'constructor' sound familiar to you?
def initialize(brand, size, color)
@brand = brand
@size = size
@color = color
end
end
trainers = Shoes.new("Kichute", 47, "Heliotrope")
puts trainers.brand # Kichute
class Hero
attr_accessor :name, :animal, :hp
def initialize(name, animal, hp)
@name = name
@animal = animal
@hp = hp
end
# It is a instance method (Good catch, Juan! 🏆)
def has_enough_hp
@hp > 5.5 ? "Able to play" : "Consider resting, #{@name}"
end
end
hero1 = Hero.new("Nakoruru", "eagle", 80)
hero2 = Hero.new("Galford", "husky", 2.9)
# Here we have invoked the object(s) method
puts hero1.has_enough_hp # Able to play
puts hero2.has_enough_hp # Consider resting, Galford
Allows classes to inherit characteristics of other classes.
class Fighter
def make_special_attack
puts "Hadouken"
end
def make_uppercut_punch
puts "Makes the uppercut move"
end
end
ryu = Fighter.new()
ryu.make_special_attack # Hadouken
ryu.make_uppercut_punch # Makes the uppercut move
# Subclass - "<" means inherits from
class SpecialFighter < Fighter
# Overwrites 'make_special_attack' method
def make_special_attack
puts "Shun Goku Satsu"
end
# Creates a new method for this class
def celebrate
puts "Is that all? You must be joking!"
end
end
gouki = SpecialFighter.new()
gouki.make_special_attack # Shun Goku Satsu
gouki.make_uppercut_punch # Makes the uppercut move
gouki.celebrate # Is that all? You must be joking!
Note: as the make_uppercut_punch
move is used by both characters there is no need to re-declare it in our subclass
.
Modules are nothing more nothing less than a container where you can store methods.
module Greeting
def say_hello(name="there")
puts "Hi #{name}."
end
def say_bye_bye(name="dear")
puts "Bye bye #{name}."
end
end
In order to access modules you must include its relative path as the example shows:
require_relative "./folder/the_name_of_your_file.rb"
include Greeting
Greeting.say_hello("Bowser") # Hi Bowser.
Error handlers are methods defined in the Exception class to deal with errors.
begin
# we have never defined the 'fav_character' variable
# so it will fire the second 'rescue' block
# and will display the customized message even
# knowing that we also tried to make a division by 0
# => Reference to control flow for more <=
fav_character["Makoto Mizuhara"]
num = 45 / 0
rescue ZeroDivisionError => e
puts e
puts "Division By Zero Error"
rescue NameError
puts "undefined local variable or method 'fav_character'."
end
If you would like to see the other error handling
in action, replace the statement fav_character["Makoto Mizuhara"]
for that one fav_character = ["Makoto Mizuhara"]
. 😉
And that's it, folks! I mean, Ruby cannot be resumed by any means to the features I have shown so far but it is a pretty good start.
The good news here are that if you have followed along until the end (and thank you a ton for doing that! 🙏), you can already use the acquired knowledge to start exploring other 'seas'. For example, why don't you try to play around with Rails (one of Ruby frameworks) a little bit?
I can see you did not skip it so don't you dare to complain later. 😂👌
" The curiosity killed the cat."
Well, if you allow me to recommend an excellent source to learn about Ruby on Rails, I would advice the Zayne's Youtube channel.
He doesn't publish videos very often but it really worth checking it out!
You can also check Web Crunch, Codemy, FreeCodeCamp and of course the Ruby Docs and Rails Guides.
Ruby is without any doubts a very powerful, beginner friendly and lovely language. As any language, it has your flaws but don't be influenced by the "which one is the best language?" war.
Ruby has been evolving a lot in the last years and counts with a very strong and respectful community that will help you whenever you need it.
I have tried to highlight some examples I personally consider important when 'meeting' Ruby for the very first time.
As you could see, the language speaks for itself. I venture to say that it is a self.describing
language. (Pun intended 🤦)
Thanks so much for your companion. I hope you have learned something new today. (It doesn't necessarily mean from this article! 🤣)
Cheerio! 👋
22