Delving a bit deeper into Ruby.
Methods
A method is a section of code created to perform a task in a program that you can reuse. A method consists of a header, a body (indented by convention) and the end keyword. The code from inside a method needs to be called in order to be executed.
def greet
puts "Hello!"
end
greet // Hello!
Let's greet a certain person and use a parameter.
def greet(person)
puts ("Hello " + person + "!")
end
greet("Nico") // Hello Nico!
Splat arguments
Splat arguments are arguments that start with an asterisk *. The asterisk tells the program that the method can receive one or more arguments.
def whats_up(greeting, *friends)
friends.each { |friend| puts "#{greeting}, #{friend}!" }
end
whats_up("What's up", "Nico", "Enzo", "Mario")
// What's up, Nico!
What's up, Enzo!
What's up, Mario!
Return
Return is used inside a method, when we want this method to give us back a value, which means executing another method. Any code that goes under the line with return is not going to be executed.
def sqrt(n)
return n * n
end
puts sqrt(3) // 9
Blocks
Blocks are similar to methods, but they don't have a name and cannot be saved to a variable. Another difference is that they run only once and cannot be called upon again. Blocks can be defined with either the keywords do and end or with { }(curly braces). A method can take a block as a parameter, for example when using each.
["enzo", "nico"].each {|string| puts "#{string[0].upcase}#{string[1..-1]}"}
// Enzo
Nico
Collect
.collect returns a copy of an array. However, we can mutate the array if we add an exclamation mark to collect.
numbers = [1, 2, 3, 4, 5]
tripled_numbers = numbers.collect { |n| n * 3 }
print tripled_numbers, " " // [3, 6, 9, 12, 15]
Yield
If a method has the keyword yield, it means that for that particular line of code, it accepts a block of code specified outside fo this method.def double(n)
yield(n)
end
double(16) { |n| puts n * 2 }
Proc
A proc is what happens when we give a bloc a name. We use them so we don't have to repeat the same code again and again. To define a block we call Proc.new and pass in our block. To call it we add & to the proc's name.
multiples_of_3 = Proc.new do |n|
n % 3 == 0
end
print (1..30).to_a.select(&multiples_of_3) // [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
.call
We use .call method to call procs, as just defining them will not run the code from inside of them.
hi = Proc.new { puts "Hello!" }
hi.call
There are also other ways of calling a lambda, but using the .call method gives more clarity.
Symbols and procs
numbers_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
strings_array = numbers_array.map(&:to_s)
print strings_array // ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
Lambdas
Lambdas are nearly identical to procs. They define blocks and their parameters and can be saved to a variable. Lambdas check the number of the passed arguments, while procs don't. Procs will ignore extra arguments and pass nil to the missing ones, but lambdas will throw an error.
You can either use the word "lambda" or the symbol "->".
lambda { puts "Hello!" } OR lambda {|param| BLOCK }
Sorting
sort! will sort our arrays of numbers and strings alphabetically or ascending. This method, however, accepts a second argument, if we want to specify how the items should be compared.
my_array = [3, 4, 8, 7, 1, 6, 5, 9, 2]
print my_array.sort! // [1, 2, 3, 4, 5, 6, 7, 8, 9]
print my_array.sort! { |num1, num2| num2 <=> num1 } // [9, 8, 7, 6, 5, 4, 3, 2, 1]
There is a combined comparison operator that looks like this: <=> . It returns 0 if the first operand equals the second. If the first operand is greater than the second it returns 1, and if the first operand is less than the second it returns -1.
day_1 = "Monday"
day_2 = "Tuesday"
puts day_1 <=> day_2 // -1
Control Flow
If, elsif, else, end
age = 13
if age < 1
puts "You're an infant"
elsif age >= 1 and age < 13
puts "You're a child"
elsif age >= 13 and age < 18
puts "You're a teenager"
else
puts "You're an adult"
end
// You're a teenager
We can also use the one-liner syntax which looks like so:
puts "You're an infant" if age < 1
Unless
sleepy = true
unless sleepy
puts "I'm in front of the computer"
else
puts "Bed time!"
end
// Bed time!
Unless also has a one-line syntax:
puts "I'm in front of the computer" unless sleepy
Boolean operators: &&, ||, !
true && true // true
true && false // false
false && true // false
false && false // false
true || true // true
true || false // true
false || true // true
false || false // false
!true // false
!false // true
Let's have a look at some examples.
boolean_1 = (3 < 4 || false) && (false || true)
print boolean_1 // true
boolean_2 = !true && (!true || 100 != 5**2)
print boolean_2 // false
Case Expressions
Case expressions are a useful solution when we check one value against a number of other values.
def get_day(day)
day_name = ""
case day
when "mon"
day_name = "Monday"
when "tue"
day_name = "Tuesday"
else
day_name = "Incorrect input"
end
return day_name
end
puts get_day("tue") // Tuesday
Conditional Assignment
If we want to assign a variable only if it hasn't already been assigned, we can use the conditional assignment operator: ||=
name = nil
print name // nothing prints
name ||= "Lena"
print name // Lena
name ||= "Eric"
print name // Lena
Concatenation operator <<
<< is used to push to arrays.
[1, 2, 3] << 4 // [1, 2, 3, 4]
alphabet = ["a", "b", "c"]
alphabet << "d" // ["a", "b", "c", "d"]
.upto and .downto
If we know what is the top or the bottom number that we are going to count to we can use .upto or .downto. What is more, these methods will also work with letters.
15.downto(5) { |num| print num, " " } // 15 14 13 12 11 10 9 8 7 6 5
"A".upto("Z") { |letter| print letter, " " } // 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
.respond_to?
In Ruby we can check if we can call a method on an object. respond_to? returns true if we can.
Since we cannot turn an array into a symbol...
[1, 2, 3].respond_to?(:to_sym) // false
Loops and iterators
While
index = 1 // we start from 1
while index <= 5 // we stop when we get to 5
print index // we execute this code
index += 1 // while adding 1 with each loop
end // 12345
Until
index = 0 // we start from 0
until index == 6 // we stop at 6
print index = index + 1 // we execute this code until index equals 6
end // 123456
For
The for loop is useful when we don't know how many times we will be looping.
Syntax:
for num in 1...10
print num
end // 123456789
Three dots mean that the final number will be excluded from the count.
Two dots mean
that the final number should be included.
The Loop Method
In Ruby, { } (curly braces) are generally interchangeable with the keywords do and end. The keyword break breaks a loop whe the condition is met.
i = 0
loop do
i += 1
print "#{i}"
break if i > 5
end
Next
We use the next keyword to skip some steps in the loop. In the example below we only print odd numbers.
for i in 1..5
next if i % 2 == 0
puts i
end // 1
3
5
.each
object.each { |item|
# Do something
}
OR
object.each do |item|
# Do something
end
.times
The .times iterator can perform a task on each item in an object a specified number of times.
5.times { print "hey " } // hey hey hey hey hey
Comments (0)
Be the first to leave a comment