Table of Contents

Introduction to Ruby

"A Programmer's Best Friend"


Ruby


Ruby Online Resources

Ruby Execution


Ruby: Syntax summary

Ruby: What might be familiar

Regular expressions

mypattern = %r|[aeiou]|
puts "String has vowels" if "This is a test" =~ /[aeiou]/

puts "String has vowels" if "This is a test".match("[aeiou]")

puts "String has vowels" if "This is a test".match( mypattern )

x = "This is a test".match(/(\w+) (\w+)/)
puts x[0]
puts x[1]
puts x[2]
puts "foobar".sub('bar', 'foo')

puts "this is a test".gsub('i', '')

x = "This is a test"
puts x.sub(/^../, 'Hello')

Arrays and hashes

x = [1, 2, 3, 4]    # array called x
x << 5              # adds 5 to array x

x = { "a" => 1, "b" => 2 }    # hash called x

# ruby-style iteration through hash:
x.each { |key, value| puts "#{key} equals #{value}" }

Ruby: What might not be familiar

Blocks end with "end"

if bool-expr [then]
  body
elsif bool-expr [then]
  body
else
  body
end

while bool-expr [do]
  body
end

for name[, name]... in expr [do]
  body
end

Multi-line strings

x = %q{This is a test
of the multi
line capabilities}

Variable interpolation

x = 10
y = 20
z = "annoying"
puts "#{x} + #{y} = #{x + y}"
puts "This is so #{z.upcase}!"

# also works # puts "This is so " + z.upcase + "!"

Ruby-style iteration

# Preferred form
some_list.each do |this_item|
  # some statements
end
		
# In Python: for this_item in some_list:
# In Perl:   foreach $this_item (some_list)

Ruby naming conventions

mystring = "Are strings mutable?"

mystring.downcase

puts mystring + " No."

mystring.downcase!

puts "#{mystring} It Depends!"

Everything except nil and false considered true

# in Ruby, 0 is considered true.
if 0
  puts "0 is true"
else
  puts "0 is false"
end

Symbols

current_situation = :good
puts "Everything is fine" if current_situation == :good
puts "PANIC!" if current_situation == :bad

# as opposed to

current_situation = "good"
puts "Everything is fine" if current_situation == "good"
puts "PANIC!" if current_situation == "bad"
person1 = { :name => "Fred", :age => 20, :gender => :male }
person1 = { :name => "Laura", :age => 23, :gender => :female }

Ruby methods (functions)

def say_hello( name )
   "Hello, " + name   # Same as: return "Hello, " + name
end
puts say_hello "Chris"   # Same as: puts say_hello( "Chris" )

Ruby Classes and Objects

Discovering methods

a = "This is a test"
puts a.methods.sort.join(' ')

Classes

class Person
   attr_accessor :name, :age, :gender
	  # note use of symbols
end

person_instance = Person.new

person_instance.name = "Robert"

person_instance.age = 52

person_instance.gender = "male"

puts person_instance.name

Intro to class inheritance in Ruby

class Pet
   attr_accessor :name, :age, :gender, :color
end

class Cat < Pet
end

class Dog < Pet
   # Dog-specific method
   def bark
	  puts "Woof!"
   end
end

class Snake < Pet
   attr_accessor :length
	  # additional attribute for Snake
end

Using instance or object variables (@varname)

# base class Shape
class Shape
end


class Square < Shape
   # consider initialize method to be the "constructor"
   def initialize( side_length )
	  @side_length = side_length
   end
   
   # Instance variables are private by default, so
   # @side_length is private unless made public with
   # attr_accessor :side_length

   # Methods are public unless declared private:
   def area
	  @side_length * @side_length
   end

   def perimeter
	  @side_length * 4
   end
end


class Triangle < Shape
   def initialize( base_width, height, side1, side2, side3 )
	  @base_width = base_width
	  @height = height
	  @side1 = side1
	  @side2 = side2
	  @side3 = side3
   end

   def area
	  @base_width * @height / 2
   end

   def perimeter
	  @side1 + @side2 + @side3
   end
end


my_square = Square.new( 5 )
my_triangle = Triangle.new( 6, 6, 7.81, 7.81, 7.81 )
puts my_square.area
puts my_square.perimeter
puts my_triangle.area
puts my_triangle.perimeter

# Attempt to change @side_length of my_square:
my_square.side_length = 10 # will fail without an attr_accessor for :side_length
puts my_square.area
puts my_square.perimeter

Using class variables (@@varname)

class Square
   def initialize
	  if defined?( @@number_of_squares )
		 @@number_of_squares += 1
	  else
		 @@number_of_squares = 1
	  end
   end


   # A class method begins with the name of the class itself
   def Square.count
	  @@number_of_squares
		 # "return" is optional
   end
end


a = Square.new
puts Square.count
b = Square.new
puts Square.count

Rubygems: Ruby packaging system

# List all available gems; hit q to quit the more pager
gem list --remote | more       

# Download and install gems
gem install nokogiri open-uri sqlite3 

Ruby and databases

SQLite with Ruby



Ruby on Rails: An introduction

Rails & the Model-View-Controller architecture

Ruby on Rails: More Information

Sample app - mydiary