Overview of Ruby¶
Everything Is An Object¶
In Ruby everything is an object. From the IRB shell lets run a couple of examples.
irb(main):001:0> 1.odd? => true
Notice the output is true
. We are able to call methods on the literal 1.
irb(main):002:0> 1.even? => false
We can also call methods on strings literals as follows :
irb(main):003:0> "Hello World".reverse => "dlroW olleH"
and we can also find the length of the string :
irb(main):004:0> "Hello World".length => 11
Comments¶
Comments in Ruby can be single line or multiple line :
- Single line comments start with a
#
symbol. - Multiple line comments use
=begin
and=end
Single line comment¶
Anything after the #
is ignored.
# This is an example of a comment puts "Hello World" # This comment come after a line of code
Multiple line comments¶
=begin This is an example of a multiple line comment. These type of comments are rare =end
Blocks and Iterators¶
Iterators are methods that act as loop constructs in Ruby. Blocks are pieces of code without names. When working with Ruby you will encounter blocks and iterators, let see some examples.
irb(main):005:0> 1.upto(5) => #<Enumerator: 1:upto(5)>
The upto is an iterator. We can use to count up to the value in brackets. We can can combine the upto iterator with a block as follows :
each iterator¶
The each iterator is used to iterate through a collection.
Define an array¶
a = [1,2] => [1, 2]
Get an iterator¶
irb(main):016:0> a.each => #<Enumerator: [1, 2]:each>
irb(main):017:0> a.map => #<Enumerator: [1, 2]:map>
Blocks¶
We can use Blocks in combination with iterators. The blocks are either single line or multiple line.
Single line blocks¶
Single line blocks start with { and end with } e.g { puts "Hello World" }
is a single line block.
Multiple line blocks¶
Multiple line block start with a do and finish with and end keyword, e.g
do puts "Hello World" end
With a single line block :
1.upto(2) { puts "Hello" } Hello Hello => 1
With a multi-line line block
1.upto(2) do p "Hello World" end
We can also generate an iterator from a range and use a block on it as follows :
irb(main):033:0> (1..2).each { p "Hello World" } "Hello World" "Hello World" => 1..2
Passing arguments to blocks¶
We can pass arguments to blocs using the || symbols after the first { bracket as follows :
(1..3).each {|value| p "Hello World #{value}" }
Running this in IRB :
irb(main):034:0> (1..3).each {|value| p "Hello World #{value}" } "Hello World 1" "Hello World 2" "Hello World 3" => 1..3
The #{}
is string interpolation in Ruby. In this case the value for index
will be concatenated with the rest of the string.
We can also use the arguments using the multi-line line block syntax as well. The || will come after the do statement as follows :
(1..3).each do |value| p "Hello #{value}" end
With IRB :
irb(main):035:0> (1..3).each do |index| irb(main):036:1* p "Hello #{index}" irb(main):037:1> end "Hello 1" "Hello 2" "Hello 3" => 1..3
We can get the powers of numbers between 1 and 10 using arguments passed within an iterator as follows :
(1..10).map { |i| 2 ** i }
In IRB we get the following :
irb(main):038:0> (1..10).map { |i| 2 ** i } => [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
The ** is the mathematical power operator.
Read a file line by line using block and iterators¶
We can also take advantage of the each iterator and use a block to output the contents of a text file as follows :
File.readlines("pgadmin.log").each { |line| p line }
The file pgadmin.log
should be in your current directory you are tunning IRB from.
Modules¶
Modules are used to define a namespace. This creates a sandbox that groups together methods, classes and constants. They are also included to extended class behavior.
Create a module¶
We use the module keyword to create a module as follows
module Greeter def greet puts "Hello World" end end
Include the module in a class¶
We can now add functionality to a class using the module as follows :
class Person include Greeter end
using the include
keyword, we can now include all the functionality provided by the module into the class. Now the Person
class can now greet
.
Instantiate a new Person object¶
We can now call greet
method after creating a new Person
object
p = Person.new p.greet
If we run from within IRB, we get the Hello World
as below :
p = Person.new => #<Person:0x007ffc4d9ff730> irb(main):013:0> p.greet Hello World
Duck Typing¶
In Ruby, objects are defined by what they can do. The type of an object is defined by its methods and attributes. Objects are not defined by their type. If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
We use the responds_to?
method to check what methods the object responds to as follows :
irb(main):019:0> (1..5).respond_to? :each => true
We can see the the (1..5) can respond to the each
method, therefore we can call each
on the object.