Print to console
puts x prints x.to_s
p x prints x.inspect (not exactly but essentially)
Gets from console
gets returns everything, including newline
gets.chomp omits the return
Only available in the local scope
10.times do
x = 10
end
# Not available here, will fail
p xAvailable in the whole application scope, usually not a great idea
10.times do
$x = 10
end
p $xAvailable in the object instance scope
class MyClass
def initialize
@x = 10
end
def x
@x
end
end
mc = MyClass.new
p mc.xAvailable in the class scope, usually not a great idea
class MyClass
@@x = 10
def self.x
@@x
end
end
p MyClass.xYou shouldn't change it but ruby will let you
CONSTANT_X = "Test"A series of characters
animal = 'fox'
other_animal = 'dog'
p "The quick brown #{animal} jumped over the lazy #{other_animal}"
p 'The quick brown #{animal} jumped over the lazy #{other_animal}'str = 'Testing'
p str.downcase
p str.upcase
p str.swapcase
p str.reversesub replaces the first occurrence, gsub replaces everything
str = 'The quick brown fox jumped over the lazy dog'
p str.gsub 'quick', 'slow'
p str
p str.gsub! 'quick', 'slow'
p strstr = ' The quick brown fox jumped over the lazy dog '
p str.stripstr = 'The quick brown fox jumped over the lazy dog'
p str.split
p str.split.size
p str.split('')
p str.split('').sizep 2 + 2
p 2 - 1
p 2 * 3
p 6 / 2
p 2 ** 5Parenthesis, exponents, multiplication, division, addition, substraction
p 5 + 15 * 20 - 2 / 6**3 - (3 + 1)
# 5 + 15 * 20 - 2 / 6**3 - 4
# 5 + 15 * 20 - 2 / 216 - 4
# 5 + 300 - 2 / 216 - 4
# 5 + 300 - 0 - 4 (2/216 is 0 because this is integer arithmetic)
# 305 - 0 - 4
# 301Ruby floating points have fixed precision, decimals have arbitrary precision
require "bigdecimal"
# integer
p 2 / 216
#float
p 2.0 / 216, Float(2) / 216
#big decimal
p BigDecimal(2) / 216You dont have to explicitely use the return clause unless it is needed for clarity or you are implementing an early return
def player_list
['John', 'Juan', 'Joao']
end
p player_listEarly return
def player_list(gender)
return ['Joanne', 'Juana'] if gender == 'F'
['John', 'Juan', 'Joao']
end
p player_list('M'), player_list(''), player_list('F')class Invoice
def self.description
'This is the invoice class'
end
end
i = Invoice.new
p Invoice.description
# This will raise an exception
#p i.descriptionclass Invoice
def initialize
@id = 10
end
def description
"This is the invoice with id=#{@id}"
end
end
i = Invoice.new
# This will raise an exception
# p Invoice.description
p i.descriptionproc
- doesnt count the args, ignores any extra args
- return inside a proc shortcuts the whole method
full_name = Proc.new { |first, last| "#{first} #{last}" }
p full_name["John", "Doe"], full_name.call("John", "Doe")lambdas
- counts the args, raises exception for incorrect count
- return inside a lambda allows the method to continue
full_name = -> (first, last) { "#{first} #{last}" }
p full_name["John", "Doe"], full_name.call("John", "Doe")def full_name(first, last)
"#{first} #{last}"
end
p full_name('Juan', 'Perez')Named args
def full_name(first:, last:)
"#{first} #{last}"
end
# This will raise an exception
# p full_name('Juan', 'Perez')
p full_name(last: 'Perez', first: 'Juan')Defaults
def full_name(first: "John", last: "Smith")
"#{first} #{last}"
end
p full_name(first: 'Juan')Splat args
def names(*people)
"People: #{people}"
end
p names('Juan'), names('Juan', 'Pedro', 'Jose')Keyword args
def register(email:, password:, **kwargs)
p "Building account for #{email}"
p "Assigning role: #{kwargs[:role]}" if kwargs[:role]
p "With plan: #{kwargs[:plan]}" if kwargs[:plan]
end
register(email: 'test@test.net', password: 'password')
register(email: 'test@test.net', password: 'password', role: 'admin')
register(email: 'test@test.net', password: 'password', plan: 'premium')i = 0
while i < 10
p i
i += 1
endarr = [23, 234, 455, 768, 838]
arr.each do |i|
p i
end
arr.each { |i| p i }arr = [23, 234, 455, 768, 838]
for i in arr do
p i
endteams = {
'engineering' => {
'dev' => 'John',
'qa' => 'Maria',
'manager' => 'George'
},
'sales' => {
'salesperson' => 'Jenny',
'manager' => 'Alex'
}
}
teams.each do |team, members|
puts team
members.each do |role, name|
puts " #{role}: #{name}"
end
endp (1..10).to_a.select(&:even?), (1..10).to_a.select { |x| x > 0 }arr = ["1", "23.0", "0", "4"]
p arr.map { |x| x.to_i }, arr.map(&:to_i), Hash[arr.map { |x| [x,x.to_i] }]arr = [1, 23.0, 0, 4]
p arr.inject(&:+)Create
arr = [1, 2, 3, 4, 4, 4, 4]
arr2 = Array.new
arr2[10] = 56
p arr, arr2Delete
arr = [1, 2, 3, 4, 4, 4, 4]
arr.delete(4)
p arr
deleted = arr.delete_at(2)
not_found = arr.delete_at(10)
p arr, deleted, not_found
arr = [1, 2, 3, 4, 4, 4, 4]
arr.delete_if { |num| num < 3 }
p arrJoin
arr = [1, 2, 3, 4]
str = arr.join(", ")
p arr, strPush/Pop
arr = Array.new
arr.push(1)
p arr
num = arr.pop
p arr, numCreate
hsh = {first: 1, second: 2, third: 3, fourth: 4, fifth: 5}
p hsh, hsh[:third]Delete
hsh = {first: 1, second: 2, third: 3, fourth: 4, fifth: 5}
#returns deleted value
deleted = hsh.delete(:third)
p hsh, hsh[:third], deleted
#returns hash
deleted = hsh.delete_if { |key, value| value % 2 == 0 }
p hsh, deletedIterate (see also Nested Iterators)
hsh.each_key do |key|
p key
end
hsh.each_value do |value|
p value
endUseful Methods
hsh = {first: 1, second: 2, third: 3, fourth: 4, fifth: 5}
hsh[:sixth] = 6
p hsh
inverted = hsh.invert
p hsh, inverted
other_hsh = {sixth: 6, seventh: 7, eighth: 8, ninth: 9, tenth: 10}
merged = hsh.merge(other_hsh)
p hsh, other_hsh, merged
arr = hsh.to_a
p hsh, arr
keys = hsh.keys
values = hsh.values
p hsh, keys, valuesDig
teams = {
'engineering' => {
'dev' => 'John',
'qa' => 'Maria',
'manager' => 'George'
},
'sales' => {
'salesperson' => 'Jenny',
'manager' => 'Alex'
}
}
p teams.dig('engineering', 'manager'), teams.dig('hr', 'manager')set = Set.new
set.add(1)
set.add(2)
set.add(3)
p set
set.add(1)
p set
set.delete(1)
p setIf/Else
x = 10
y = 5
if x == y
p 'x and y are the same'
else
p 'x and y are different'
endUnless
arr = [1, 2, 3, 4, 5]
empty_arr = []
p arr unless arr.empty?
p empty_arr unless empty_arr.empty?Multiple if/else
x = 10
y = 5
z = 1
if x == y
p 'x and y are the same'
elsif x > y
p 'x is greater than y'
elsif x > z
p 'x is greater than z' # this will never run
else
p 'y is greater than x'
endCompound conditionals
x = 10
y = 5
z = 10
p 'x is equal to y and z' if x == y && x == z
p 'x is equal to y or z' if x == y || x == zEverything in Ruby is an object.
Setters, getters and methods
class Animal
attr_accessor :name, :age
def info
"#{@name} is #{@age} years old"
end
end
a = Animal.new
a.name = 'Dog'
a.age = 3
p a.infoInitializer method
class Animal
attr_accessor :name, :age
def initialize(name: 'unknown', age: 0)
@name = name
@age = age
end
def info
"#{@name} is #{@age} years old"
end
end
a = Animal.new
p a.info
a = Animal.new(name: 'dog', age: 3)
p a.infoInheritance / polymorphism
class Animal
attr_accessor :name, :age
def initialize(name: 'unknown', age: 0)
@name = name
@age = age
end
def info
"#{@name} is #{@age} years old"
end
def noise
'...'
end
end
class Dog < Animal
def initialize(name: 'dog', age: 0)
super(name: name, age: age)
end
def noise
'Bow wow'
end
end
class Cat < Animal
def initialize(name: 'cat', age: 0)
super(name: name, age: age)
end
def noise
'Meow meow'
end
end
a = Animal.new
p a.info, a.noise
a = Dog.new
p a.info, a.noise
a = Cat.new
p a.info, a.noisePrivate methods
class Animal
attr_accessor :name, :age
def initialize(name: 'unknown', age: 0)
@name = name
@age = age
end
def info
"#{@name} is #{@age} years old"
end
private
def secret_method
'secret message'
end
end
a = Animal.new(name: 'Dog', age: 3)
p a.info
p a.secret_method # => ErrorModules
module Tools
module StringTools
class << self
def count_words(string)
split_words(string).size
end
private
def split_words(string)
string.split
end
end
end
end
p Tools::StringTools.count_words('Hello world')- r read
- a append
- w write
- w+ read/write
- a+ read/append
- r+ read/write/append
Creating a file
File.open('test1.txt', 'w+') { |f| f.write('Testing tests...') }
file = File.open('test2.txt', 'w+')
file.puts('Testing tests...')
file.closeReading files
txt = File.read('test1.txt')
p txtDeleting files
File.delete('test2.txt')Appending to a file
10.times do
sleep 1
p 'Record saved'
File.open('test.txt', 'a') {|f| f.puts "Record saved at #{Time.now}"}
endbegin
p 8/0
rescue StandardError => e
p "Error occurred: #{e}"
endstr = 'The quick 12 brown foxes jumped over the 10 lazy dogs'
# Case sensitive
p str =~ /z/ ? 'Contains z' : 'Does not contain z', str =~ /Z/ ? 'Contains z' : 'Does not contain z'
# Case insensitive
p str =~ /z/i ? 'Contains z' : 'Does not contain z'
p(str.to_enum(:scan, /\d+/).map { Regexp.last_match })arr = ['data.txt', 'example.rb', 'data2.txt', 'data3.txt.xlsx', 'hack.rb', 'data5.txt']
p arr.grep(/w*.rb/), arr.grep(/w*.txt/), arr.grep(/w*.xlsx/)- A method with a
!generally means the variable will be modified in place - Use symbols when you want to create an identifier, and use strings for data. Strings are mutable, symbols are inmutable.
- HashWithIndifferentAccess is a special kind of hash that allows you to access its keys using either strings or symbols interchangeably