IT212 Data Structure

Unit 2: Ruby Programming

R Batzinger

2026-01-17

Ruby programming language

Why Ruby?

  • Ruby is a dynamic, object-oriented programming language known for its simplicity and productivity.
  • Ruby real-world applications span web development, automation, web scraping, DevOps, and graphics often through library extentions.
  • Ruby provides development tools to support design, testing, documentation and formatting of code.
  • Ruby fully supports Asian languages using both Unicode and national code spaces developed by Yukihiro Matsumoto
  • Ruby facilitates the inspection of storage requirements of data structures

Ruby development tools

  • Robocop - A Ruby static code analyzer and formatter, based on the community Ruby style guide.
  • rdoc - A Ruby static code analyzer and formatter, based on the community Ruby style guide.
  • Rake - a tool that uses standard Ruby syntax.
  • Test::Unit - checks that code is compatible with design assertions
  • Cucumber - a behavior driven development system to tests the code against the design specifications
  • Rmagick - a graphic library that interfaces with imagemagick to create and modify graphic images.
  • DBI: provides a database-agnostic API to load the appropriate DBD (Database Driver) for your database (e.g., MySQL, PostgreSQL, SQLite)

Ruby resources

  • Central Ruby site: https://www.ruby-lang.org/en/

  • Online ide: https://try.ruby-lang.org/playground/

  • Download page:

    • Windows: https://rubyinstaller.org/downloads/
    • Other Os: https://www.ruby-lang.org/en/documentation/installation/
  • Tutorial: https://try.ruby-lang.org https://pine.fm/LearnToProgram/

  • Documentation: https://ruby-doc.org/

  • Programming Manual: https://ruby-doc.org/docs/ruby-doc-bundle/ProgrammingRuby/index.html

Ruby standard data types

  • Numerical primitive objects
    • Integer (with Automatic conversion between Fixnum and Bignum)
    • Float
    • Rational
    • Complex
  • Textual primitive objects
    • Characters (with code point)
    • Symbols
  • Collective objects
    • Object Classes
    • Array - (includes stacks and queues)
    • Hash - (associated array)
    • String
    • Enumerable

Code examples


#!/usr/bin/env ruby
# Demonstration of Ruby's standard numeric data types

puts "Ruby Data Types".upcase

def unitheader(header)
  puts
  puts header
  puts "-" * 65
end

def example(lbl, op)
   x = eval(op)
   puts " #{lbl.ljust(12)}, #{op.ljust(27)} #{x} (#{x.class})"
end

unitheader("Integer examples:")
example("@int_a","@int_a = 42")
example("@int_b","@int_b = -100")
example("Sum:","@int_a + @int_b")

unitheader("Float examples:")
example("@float_a","@float_a=3.14159")
example("@float_b","@float_b = -0.5")
example("Product:","@float_a * @float_b")

unitheader("Rational examples:")
example("@rational_a","@rational_a = Rational(2,3)")
example("@rational_b","@rational_b = 5r")
example("Sum:","@rational_a + @rational_b")

unitheader("Complex examples:")
example("@complex_a","@complex_a = Complex(2,3)")
example("@complex_b","@complex_b = 4 + 5i")
example("Sum:","@complex_a + @complex_b")

unitheader("Type conversions:")
example("Int2Float:","@int_a.to_f")
example("Float2Int","@float_a.to_i")
example("Int2Rational","@int_a.to_r")
example("Int2Complex","@int_a.to_c")

unitheader("Automatic type promotion:")
example("Int2Float", "@int_a + @float_a")
example("Int2Rational","@int_a + @rational_a")
example("Rational2Flt","@rational_a+@float_a")
example("Complex2Int","@complex_a + @int_a")

unitheader("Edge case: very large integers")
example("@bigInt", "@big_int = 10**20")
example("inc(@bigInt)","@big_int += 1")
puts "-" * 65

Output

RUBY DATA TYPES

Integer examples:
-----------------------------------------------------------------
 @int_a      , @int_a = 42                 42 (Integer)
 @int_b      , @int_b = -100               -100 (Integer)
 Sum:        , @int_a + @int_b             -58 (Integer)

Float examples:
-----------------------------------------------------------------
 @float_a    , @float_a=3.14159            3.14159 (Float)
 @float_b    , @float_b = -0.5             -0.5 (Float)
 Product:    , @float_a * @float_b         -1.570795 (Float)

Rational examples:
-----------------------------------------------------------------
 @rational_a , @rational_a = Rational(2,3) 2/3 (Rational)
 @rational_b , @rational_b = 5r            5/1 (Rational)
 Sum:        , @rational_a + @rational_b   17/3 (Rational)

Complex examples:
-----------------------------------------------------------------
 @complex_a  , @complex_a = Complex(2,3)   2+3i (Complex)
 @complex_b  , @complex_b = 4 + 5i         4+5i (Complex)
 Sum:        , @complex_a + @complex_b     6+8i (Complex)

Type conversions:
-----------------------------------------------------------------
 Int2Float:  , @int_a.to_f                 42.0 (Float)
 Float2Int   , @float_a.to_i               3 (Integer)
 Int2Rational, @int_a.to_r                 42/1 (Rational)
 Int2Complex , @int_a.to_c                 42+0i (Complex)

Automatic type promotion:
-----------------------------------------------------------------
 Int2Float   , @int_a + @float_a           45.14159 (Float)
 Int2Rational, @int_a + @rational_a        128/3 (Rational)
 Rational2Flt, @rational_a+@float_a        3.8082566666666664 (Float)
 Complex2Int , @complex_a + @int_a         44+3i (Complex)

Edge case: very large integers
-----------------------------------------------------------------
 @bigInt     , @big_int = 10**20           100000000000000000000 (Integer)
 inc(@bigInt), @big_int += 1               100000000000000000001 (Integer)
-----------------------------------------------------------------

Ruby installation

https://www.ruby-lang.org/en/downloads/

  • Install Ruby
  • Install robocop
  • Notepad++

Ruby Cheatsheet

Basics .{scrollable}

  • $ irb: to write ruby in the terminal
  • don’t use ' in ruby, use " instead
  • you can replace most {} with do end and vice versa –– not true for hashes or #{} escapings
  • Best Practice: end names that produce booleans with question mark
  • CRUD: create, read, update, delete
  • [1,2].map(&:to_i)
  • integer: number without decimal
  • float: number with decimal
  • tag your variables:
    • $: global variable
    • @: instance variable
    • @@: class variable
  • 1_000_000: 1000000 –– just easier to read

Vars, Constants, Arrays, Hashes & Symbols

my_variable = “Hello”
my_variable.capitalize! # ! changes the value of the var same as my_name = my_name.capitalize
my_variable ||= "Hi" # ||= is a conditional assignment only set the variable if it was not set before.

Constants

MY_CONSTANT = # something

Arrays

my_array = [a,b,c,d,e]
my_array[1] # b
my_array[2..-1] # c , d , e
multi_d = [[0,1],[0,1]]
[1, 2, 3] << 4 # [1, 2, 3, 4] same as [1, 2, 3].push(4)

Hashes

hash = { "key1" => "value1", "key2" => "value2" } # same as objects in JavaScript
hash = { key1: "value1", key2: "value2" } # the same hash using symbols instead of strings
my_hash = Hash.new # same as my_hash = {} – set a new key like so: pets["Stevie"] = "cat"
pets["key1"] # value1
pets["Stevie"] # cat
my_hash = Hash.new("default value")
hash.select{ |key, value| value > 3 } # selects all keys in hash that have a value greater than 3
hash.each_key { |k| print k, " " } # ==> key1 key2
hash.each_value { |v| print v } # ==> value1value2

my_hash.each_value { |v| print v, " " }
# ==> 1 2 3

Symbols

:symbol # symbol is like an ID in html. :symbol != "symbol"
# Symbols are often used as Hash keys or referencing method names.
# They can not be changed once created. They save memory (only one copy at a given time). Faster.
:test.to_s # converts to "test"
"test".to_sym # converts to :test
"test".intern # :test
# Symbols can be used like this as well:
my_hash = { key: "value", key2: "value" } # is equal to { :key => "value", :key2 => "value" }

Functions to create Arrays

"bla,bla".split(“,”) # takes string and returns an array (here  ["bla","bla"])

Methods

Methods

def greeting(hello, *names) # *names is a split argument, takes several parameters passed in an array 
  return "#{hello}, #{names}"
end

start = greeting("Hi", "Justin", "Maria", "Herbert") # call a method by name

def name(variable=default)
  ### The last line in here gets returned by default
end

Classes

custom objects

class Person # class names are rather written in PascalCase (It is similar to camelCase, but the first letter is capitalized)
  @@count = 0
  attr_reader :name # make it readable
  attr_writer :name # make it writable
  attr_accessor :name # makes it readable and writable

  def Methodname(parameter)
    @classVariable = parameter
    @@count += 1
  end

  def self.show_classVariable
    @classVariable
  end

  def Person.get_counts # is a class method
    return @@count
  end

  private

  def private_method; end # Private methods go here
end

matz = Person.new("Yukihiro")
matz.show_name # Yukihiro

Inheritance

class DerivedClass < Base
  def some_method
    super(optional args) # 
      # Some stuff
    end
  end
end

Modules

module ModuleName 
end

Math::PI # using PI constant from Math module. 

require 'date' # to use external modules.
puts Date.today # 2016-03-18

module Action
  def jump
    @distance = rand(4) + 2
    puts "I jumped forward #{@distance} feet!"
  end
end

class Rabbit
  include Action 
  extend Action 
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

peter = Rabbit.new("Peter")
peter.jump # include
Rabbit.jump # extend

Blocks & Procs

Code Blocks

Blocks are not objects. A block is just a bit of code between do..end or {}. It’s not an object on its own, but it can be passed to methods like .each or .select.

def yield_name(name)
  yield("Kim") # print "My name is Kim. "
  yield(name) # print "My name is Eric. "
end

yield_name("Eric") { |n| print "My name is #{n}. " } 
yield_name("Peter") { |n| print "My name is #{n}. " }

Proc

Saves blocks and are objects. A proc is a saved block we can use over and over.

cube = Proc.new { |x| x ** 3 }
[1, 2, 3].collect!(&cube) # [1, 8, 27]
cube.call 

Lambdas

lambda { |param| block }
multiply = lambda { |x| x * 3 }
y = [1, 2].collect(&multiply) # 3 , 6

Calculation

  • Addition (+)
  • Subtraction (-)
  • Multiplication (*)
  • Division (/)
  • Exponentiation (**)
  • Modulo (%)
  • The concatenation operator (<<)
  • Increment: 1 += 1 <br> (1++ and 1– do not exist in ruby)
  • Concatenation: "A " << "B" (yields) "A B"
  • String/Numerical interpolation: “A #{4} B”

Commenting

# single line comment

=begin
This is indeed
a multiline comment
=end

Conditionals

If

if 1 < 2
  puts “one smaller than two”
elsif 1 > 2 
  puts “elsif”
else
  puts “false”
end

puts "be printed" if true
puts 3 > 4 ? "if true" : "else" 

Unless

unless false
  puts “I’m here”
else
  puts “not here”
end

puts "not printed" unless true

Case

case my_var
  when "some value"
    ###
  when "some other value"
    ###
  else
    ###
end

or

case my_var
  when "some value" then ###
  when "some other value" then ###
  else ###
end

Logical functions

  • &&: and

  • ||: or

  • !: not

  • (x && (y || w)) && z: use parenthesis to combine arguments

  • flexibility in expression

problem = false
print "Good to go!" if !problem 
print "Good to go!" unless problem

Printing & Putting

puts "first line" # puts text in a separate line

print "blank"
puts "test" # Both both on a single line

String Methods

"Hello".length # 5
"Hello#{123}" # Hello123
"Hello".reverse # “olleH”
"Hello".upcase # “HELLO”
"Hello".downcase # “hello”
"hello".capitalize # “Hello”
"Hello".include? "i" # equals to false because there is no i in Hello
"Hello".gsub!(/e/, "o") # Hollo
"1".to_i # transform string to integer –– 1
"test".to_sym # converts to :test
"test".intern # :test
:test.to_s # converts to "test"

User Input

gets # reads a line
gets.chomp # removes new line char

Loops

While loop

i = 1
while i < 11
  puts i
  i = i + 1
end

Until loop

i = 0
until i == 6
  puts i
  i += 1
end

For loop

for i in 1...10 
  puts i
end

Loop iterator

i = 0
loop do
  i += 1
  print "I'm currently number #{i}” 
  break if i > 5
end

Next

for i in 1..5
  next if i % 2 == 0
  print i
end

.each

things.each do |item|
  print “#{item}"
end

on hashes like so:

hashes.each do |x,y|
  print "#{x}: #{y}"
end

.times

10.times do
  print “this text will appear 10 times”
end

.upto / .downto

1.upto(5) { |x| print x, " " }     # 1 2 3 4 5
"a".upto("c") { |x| print x, " " } # a b c

Sorting & Comparing

array = [5,4,1,3,2]
array.sort! # = [1,2,3,4,5] 
"a" <=> "b" # 0 if a = b, 1 if a > b, -1 if a < b
array.sort! { |a, b| b <=> a } # to sort from Z to A 

Table of Contents

1.is_a? Integer # returns true
:1.is_a? Symbol # returns true
"1".is_a? String # returns true
[1,2,3].collect!() # does something to every element (overwrites original with ! mark)
.map() # is the same as .collect
1.2.floor # 1 # rounds down to the nearest integer.
cube.call # call calls procs directly
Time.now # displays the actual time

Ruby in 4 hrs

Key Features Users can search for local businesses, view Street View panoramas, and access offline maps. The mobile app integrates live GPS navigation and business reviews from millions of contributors. ​

Thailand Context In Chiang Mai, such as your location in San Pu Loei, gmap proves useful for navigating rural areas, finding nearby attractions like Doi Suthep, or checking traffic on routes to the city center. Specialized Thai tools like gmap.mhesi.go.th offer project dashboards for local development. ​

Alternatives GMAP Analytics focuses on business location intelligence, while the GMAP tool assesses environmental risks in agro-commodities. For immersive views, try Google Earth or Street View. ​

A brief Introduction

A 4-hour Ruby basics course:

  • hands-on coding with simple examples and exercises
  • building from zero knowledge to writing functional programs
  • Goal: understanding the basic of Ruby programming for the pirpose of reading, writing and running code snippets that demonstrate aspects of data structures

Hour 1: Setup and Fundamentals

  1. Download and install ruby

  2. Determine if ruby is available and working:

    1. Open the terminal
    2. enter the command: ruby -v to determine the version of the ruby
    3. create a text file by the name of hello.rb that contain this line:

    puts “Hello, World!”

    1. run the file: ruby hello.rb
  3. Try storing different type of data by typing the following content into a file named, datatest.rb:

    a = 12 b = 3.14159265358979323846264338327950288419716939937510 c = “Name:ohn Smith:2 Sunset Dr.hiang Mai” d = ‘Name:ohn Smith:2 Sunset Dr.hiang Mai’ e = 3 < 5 f = Math::PI.to_r g = :red h = [:red,:orange,:yellow,:green,:cyan,:blue,:purple,:black,:white] i = {:red => “#FF0000”, :orange => “#FF8800#”, :yellow => “#FFFF00”, :green => “#00FF00”, :cyan => “#00FFFF”, :blue => “#0000FF”, :purple => “#FF00FF”, :black => “#000000”, :grey => “#999999”, :white => “#FFFFFF”}

    data = [a,b,c,d,e,f,g,h,i]
    
    data.each do |value| puts value; end
    
    data.each do |value| puts value.class; end

basic data types (strings, integers, floats, booleans), and simple arithmetic/string operations like name.length or “hello” + ” world”.

Hour 2: Control Flow and Input

Teach conditionals (if, else, elsif, ternary condition ? true : false), comparison operators (==, >, &&), and user input (gets.chomp). Add case statements for multi-way branching. Demo a basic number guessing game.

Hour 3: Collections and Loops

Explain arrays (arr = [1,2,3]; arr[0]), hashes (hash = {key: “value”}), and iteration (each, for, while, times). Cover common methods like push, pop, length, keys, values, select. Build a Mad Libs-style story generator.

Hour 4: Methods and Objects

Define methods (def greet(name); puts “Hi #{name}”; end), parameters, return values, and scope. Introduce classes (class Person; def initialize(name); @name = name; end; end), basic objects, and a simple attr_accessor. Wrap with a mini-project like a quiz or calculator, plus debugging tips (p vs puts, binding.pry).