---
description: Describe about Ruby language syntax
---

# Ruby Syntax

**Print**

```ruby

# Print with new line
puts "Hello world"

# Print without new line
print "hello"

# Can use 'p' as 'puts'
p "Hello world" 
```

**Comment**&#x20;

```ruby
# use # for comment one line
# use =begin and =end for comment multiple line

=begin 
    This is an exmaple.
    For comment multiple line.
=end

```

**Variable Type**

```ruby
# Number
age = 22
money = 200.00

# Boolean
isValid = true

# String
name = "Boby"

# Symbol
symbol = :name
# We use symbol for key because the performance for access data is better
countries1 = {
    :th => "Thailand",
    :jp => "Japanse",
    :de => "German"
}


# Constant 
# it will start with capital lettere
PI = 3.14

# Global Variable
$amount = 200
```

**\*\*\* Method \*\*\***

```ruby
# In every ruby variable it will be object. 
# Example If we call operation in ruby It mean we use method of object

p 1 + 2 ;# equal p 1.+(2) 

# mean  1 call method + and argument is 2
```

**String Method**

```ruby
name = "Boby"
# Length String
p name.length; #output = 4

# Downcase String
p name.downcase; #output = "boby"

# Upcase String
p name.upcase; #output = "BOBY"

# Reverse String
p name.reverse; #output = "yboB"
```

**Integer Method**

```ruby
num = 3

# Integer to Float
p num.to_f; #output = 3.0

# Integer to String
p num.to_s; #output = "3"

# Check Even
p num.even?; #output = false

# Check Odd
p num.odd?; #output = true
```

**Show All methods of object**

```ruby
num = 3

# Show all methods
p num.methods
#output = [:-@, :**, :<=>, :upto, :<<, :<=, :>=, :==, :chr, :===, :>>, :[], :%, :&, :inspect, :*, :+, :ord, :-, :/, :size, :succ, :<, :>, :to_int, :coerce, :to_s, :to_i, :to_f, :divmod, :to_r, :fdiv, :modulo, :remainder, :abs, :magnitude, :integer?, :floor, :ceil, :round, :truncate, :^, :odd?, :even?, :allbits?, :anybits?, :nobits?, :downto, :times, :pred, :pow, :bit_length, :digits, :lcm, :gcdlcm, :gcd, :numerator, :denominator, :rationalize, :next, :div, :|, :~, :+@, :eql?, :singleton_method_added, :i, :real?, :zero?, :nonzero?, :finite?, :infinite?, :step, :positive?, :negative?, :arg, :clone, :dup, :rect, :real, :imaginary, :imag, :abs2, :angle, :phase, :conjugate, :rectangular, :to_c, :polar, :conj, :quo, :between?, :clamp, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :instance_variable_get, :instance_variable_set, :instance_variables, :singleton_method, :method, :public_send, :define_singleton_method, :public_method, :extend, :to_enum, :enum_for, :=~, :!~, :respond_to?, :freeze, :object_id, :send, :display, :nil?, :hash, :class, :singleton_class, :itself, :yield_self, :then, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :equal?, :!, :__id__, :instance_exec, :!=, :instance_eval, :__send__]
```

**Create Object**

```ruby
# Implicit Way
# Integer, Float and Symbol can use only implicit way
name = "hello"
n = 1

# Explicit Way
customer = Array.new 
customer.push(1,2,3)
```

**Create Class**

```ruby
# Same concept as Java every class inherited from Object class
class Human
  DEFAULT_NAME = "default_name"
  
  # Generate getter/setter
  attr_accessor(:name, :age)

  # Generate getter
  # attr_reader(:name,:age)
  # Generate setter
  # attr_writer(:name,:age)

  # Constructor
  def initialize(name , age)
  # @ = this in java 
    @name = name
    @age = age
  end

  def detail
    p "My name is #{@name} and I'm #{@age} years old."
  end
  
  # We can also add 'private' keyword to let method become private
  # (Default is public) 
  # protected = can access from class(self) / child class
  private def testPrivate
    p "This method is private."  
  end

  # add self like a static method
  def self.info
    p "This is Human class"
  end
end


h1 = Human.new"Boby",12
h2 = Human.new"John",13

h1.detail; #output = My name is Boby and I'm 12 years old.
h2.detail; #output = My name is John and I'm 13 years old.

# Access constant variable inside the class from outside
puts Human::DEFAULT_NAME
```

**Condition**

```ruby
# Normal if
if a == 10
    p "a is equal to 10."
end

# Ternary if
money = money< 0 ? 0 : money

# If in line
gender = "male"
p "I'm a man" if gender == "male"

# Multiple condition
if a > 10
    p "a is more than to 10."
elsif a == 10    
    p "a is equal to 10."
else
    p "a is less than 10."
end   

# Unless
x = 2
y = 3
unless x == y
    p "x is not equal y."
end
```

**Loop**

```ruby
# While Loop
i = 1 
while i <= 3
    print i, " "
    i = i + 1
end
#output = 1 2 3 4

# Until (It will run until condition true)(In contrast with While)
i = 3
until i == 0
  print i, " "
  i-=1
end
#output = 3 2 1

# For Loop
for i in (1..4)
    print i, " "
end
#output = 1 2 3 4

# break = exit loop
# next = continue in other language (go to next loop)
# redo = rerun this round of loop

```

**Method**

```ruby
# We need to define method before calling

# can set default value in argument
def calcualte(a = 0,b)
    return a+b
end

p calculate(2,3) #output = 5 

# can set multiple argument
def cal2(*a)
    p a
end

p cal2(2,3,4)
#output = [2,3,4]

# In method we will have 2 character behind method
# 1. ! = method will upadted the existing object
# 2. ? = method will return boolean

#Ex1
a = "ruby"
c = a.upcase
p a #output= "ruby"
a.upcase!
p a #output= "RUBY"

#Ex2
year = 2019
puts year.even? #output = false
puts year.odd? #output = true

```

**Array**

```ruby
numbers = [1,2,3,4,5,6]

# Loop Array
# Strategy
# 1. While
# 2. For
# 3. Foreach

sum = 0
numbers.each {|n|
  sum+=n
  print "#{n}, "
}
# output= 1, 2, 3, 4, 5, 6,

puts
p "Sum: #{sum}"
#output= "Sum: 21"

# Reverse
numbers.reverse.each { |n| print "#{n} ,"}
# output= 6 ,5 ,4 ,3 ,2 ,1 ,

puts
# Sort
numbers2 = [2,7,3,1,6]
numbers2.sort.each { |n| print "#{n} ,"}
# output= 1 ,2 ,3 ,6 ,7 ,

puts
# each index it will return index not value
countries = ["Russia", "Germany", "Thailand", "Singapore", "Australia"]
countries.each_index { |index|
  puts "countries[#{index}]: #{countries[index]}"
}
# output=
# countries[0]: Russia
# countries[1]: Germany
# countries[2]: Thailand
# countries[3]: Singapore
# countries[4]: Australia

# Convert object to array
p (1..10).to_a
# output= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

hash = {
  "USD": "United States Dollar",
  "EUR": "Euro",
  "THB": "Thai Baht"
}
p hash.to_a
#output= [[:USD, "United States Dollar"], [:EUR, "Euro"], [:THB, "Thai Baht"]]

colors = ["red","green","yellow","orange"]
p colors.length
# output= 4

# Add value to array
colors.push"blue", "pink"
p colors
# output= ["red", "green", "yellow", "orange", "blue", "pink"]

# Merge Array
color2 = ["black","white","grey"]
p colors + color2
# output= ["red", "green", "yellow", "orange", "blue", "pink", "black", "white", "grey"]
p colors
# output= ["red", "green", "yellow", "orange", "blue", "pink"]
# Concat different from '+' because it change exist array
colors.concat color2
p colors
["red", "green", "yellow", "orange", "blue", "pink", "black", "white", "grey"]

# Shift = remove first element of array
# Pop = remove last element of array
# Unshift = add element in front of array

names = ["Bob","Adam"]

names.unshift "John"
p names
# output= ["John", "Bob", "Adam"]

names.shift
p names
# output = ["Bob","Adam"]

names.pop
p names
# output = ["Bob"]

# Insert with specific position
lang = ["PHP", "Python", "C", "Java"]
# index, value
lang.insert(1, "Ruby")
p lang
# output= ["PHP", "Ruby", "Python", "C", "Java"]

# Delete element from position
lang.delete_at 4
p lang
# output= ["PHP", "Ruby", "Python", "C"]

# Clear = remove all element
lang.clear
p lang
# output= []

# Slice = slice array
products = ["MacBook","Iphone4","Apple Watch","Adapter"]
# Not change existing array
p products[2,3]
# output= ["Apple Watch", "Adapter"]
p products[1..2]
# output= ["Iphone4", "Apple Watch"]

# Check empty array
p [].empty?
# output= true
```

**Inherit Class**

```ruby
class Animal
  attr_accessor(:leg)

  def initialize(leg)
    @leg = leg
  end

  def eat
    puts "I'm eating"
  end
end

# '<' syntax for extend class
class Dog < Animal

  attr_accessor(:color, :breed)

  def initialize(color, breed,leg)
    super(leg)
    @color = color
    @breed = breed
  end

  def bark
    puts "#{@breed} is barking"
  end

  def run
    puts "#{@breed} is running with #{@leg} legs"
  end
end

# Creating objects
d = Dog.new("Brown","Husky",4)

d.eat
d.bark
d.run
```

**Module**

```ruby
module Company
  class Employee

    attr_accessor(:name, :salary, :department)

    def initialize(name, salary, department)
      @name = name
      @salary = salary
      @department = department
    end

  end

  class Department

    attr_accessor(:name)

    def initialize(name)
      @name = name
    end

  end
end

# Access class using this syntax : ModuleName::ClassName
emp = Company::Employee.new("Mateo", 98000, "Engineering")
print "#{emp.name} works in #{emp.department} department"
puts " and his salary is #{emp.salary}"

departments = [
  Company::Department.new("Engineering"),
  Company::Department.new("Marketing"),
  Company::Department.new("Customer Service")
]

puts "There are #{departments.length} departments in our company"
departments.each { |d|
  puts d.name
}

# include = import other module

```

**Exception**

```ruby
# Every error will extend from class called Standard Error
# We use 'begin' and 'rescue' as try/catch

# Ex1
begin
  2/0

# recuse = catch
rescue => e
  p e.message
  p "Divider must not be zero, please try again"
end
# output=
# "divided by 0"
# "Divider must not be zero, please try again"

# Specific exception
begin
  ["Ruby", "PHP", "Python"].first(-5)
  no_method
rescue ArgumentError => exception
  # Handle ArgumentError
  puts exception.inspect
rescue NameError => exception
  # Handle NameError
  puts exception.inspect
rescue => exception
  # Handle any StandardError
  puts exception.inspect
end
# output= #<ArgumentError: negative array size>

# Throw Exception
# We used 'raise' as throw in other language
# else = run when program will not be error
# ensure = run every time even program error
begin
  # Throw exception
  raise StandardError.new "Hello world error"
rescue => e
  p e.message
else
  p "Program pass"
ensure
  p "This Program is running"
end
# output= 
# "Hello world error"
# "This Program is running"

```
