Intro to Ruby

Class 3

Welcome!

Girl Develop It is here to provide affordable and accessible programs to learn software through mentorship and hands-on instruction.

Some "rules"

  • We are here for you!
  • Every question is important
  • Help each other
  • Have fun

Review

Do you have any questions or concepts from yesterday that you'd like to discuss?


  • Terminal
  • Variables, Arithmetic & Objects
  • Methods and Error Messages
  • Boolean Expressions
  • Conditions - if, elsif, else
  • Loops - while, for

What we will cover in this section

  • Arrays
  • Hashes
  • Methods
  • Objects
  • Object Oriented Programming

Arrays

Arrays have square brackets and can be filled with any type of object: integers, floats, strings, even other arrays or hashes.


new_array = [1, 3, 5, 89, 212, 7, -100]
arr = ["wow", "woooo", "zowie"]
array = Array.new #will have no elements inside it initially
varied_array = ["one", 2, "THREE", 0.4, ["five", 6]]

# methods to get information about an array
new_array.length
new_array.count
arr.include?("yee ha")
            

Arrays are a great way to keep track of information that changes frequently.

Accessing Elements in an Arrays

Arrays are ordered and are integer-indexed, starting at 0.

Elements can be accessed by their position.


new_array = [1, 3, 5, 89, 212, 7, -100]
arr = ["wow", "woooo", "zowie"]

new_array[0]    # returns the zeroth element 
arr[2]          # returns the third element 
arr[-1]         # returns the last (1st from the end) element 
new_array.last  # returns the last element 
new_array[1..2] # returns the second and third elements
arr.first       # returns the first element 
            

Adding & Deleting From Arrays

Adding and removing items to an array can be done in a variety of ways. These are the most common.


arr = ["wow", "woooo", "zowie"]

#add
arr.push("hot diggity") # adds argument as last element
arr << "yikes"          # adds argument as last element

#remove
arr.delete("wow")       # deletes the element that matches argument
arr.pop                 # removes and returns the last element
            

More Array Methods

Arrays are used a lot in Ruby. There are a lot of cool methods available for them.


arr = ["dog", "cat", "turtle", "parakeet", "ferret"]

arr.index("dog")  # returns the index of the element that matches argument
arr.join          # returns a string made up of all the elements
arr.clear         # removes all elements from the array
arr.reverse       # returns new array with same elements, reversed
arr.shuffle       # returns new array with same elements, shuffled
arr.uniq          # returns a new array with only unique elements     
arr.size          # returns the number of elements in the array
arr.empty?        # returns a boolean 
            

Learn more about arrays http://www.ruby-doc.org/core-2.1.0/Array.html

Hashes

Hashes have curly braces and hash rockets and can be filled with any data type: integers, floats, strings, even arrays and hashes.


grades_hash = { "Jane Doe" => 10, "Jim Doe" => 6, "Jan Doe" => 8}
new_hash = { 1 => "a", "d" => 12, "f" => 35 }

# methods to find information about hashes 
new_hash.length
grades_hash.count 
grades_hash.size
grades_hash.has_key?("Jan Doe")
new_hash.has_value?(35)

        

Syntax:

{ key => value, key => value }

Accessing Elements in Hashes

Hashes are unordered. Hashes are like dictionaries, with unique key / value pairs.

Because hashes can have any type of object as an idex, and are unordered, we must access values by their key.


grades_hash = { "Jane Doe" => 10, "Jim Doe" => 6, "Jan Doe" => 8}
new_hash = { 1 => "a", "d" => 12, "f" => 35 }

grades_hash["Jane Doe"]   # returns 10, the value of this key
new_hash["d"]             # returns 12, the value of this key
grades_hash.first         # returns first key/value pair... probably
        

Adding & Removing from Hashes


new_hash = { 1 => "a", "d" => 12, "f" => 35 }

# add
new_hash["z"] = 43   # adds a new key/value pair "z" => 43 

#remove
new_hash.delete("d") # removes key/value pair with specified key   
new_hash.clear       # removes all key/value pairs 
        

More Hash methods


chapters = {"My Early Home" => (1..15), "The Hunt" => (16..28), 
        "My Breaking In" => (29..46), "Birtwick Park" => (46..60)}

chapters.count      # returns number of key/value pairs in hash
chapters.keys       # returns an array of all the keys in hash
chapters.has_key?("How It Ended")  # returns a boolean
chapters.to_a       # converts hash to an array of arrays
chapters.invert     # returns new hash with old one's values 
                  # as keys and keys as values
          

Learn more about hashes http://www.ruby-doc.org/core-2.1.1/Hash.html

Enumerable

Arrays and Hashes are both members of the Enumerable class. There are a lot of cool methods available for Enumerable, including each.

.each with Ranges

This is the simplest!


(3..8).each do |n|
puts n * 4
end
        

.each with Arrays

Can be simple or more complex, depending on the array.


pets_array = ["dog", "cat", "turtle", "parakeet", "ferret"]

pets_array.each do |p|
puts "I like #{p}s!!"
end


deep_array = [["mountain", "desert"], ["ocean", "sky"]]

deep_array.each do |p| 
puts "I like #{p.first}s!!"  # each element is also an array
end
        

.each with Hashes

Each element has a key and value that needs to be dealt with.


grades_hash = { "Jane Doe" => 10, "Jim Doe" => 6, "Jan Doe" => 8}

grades_hash.each do |key, value|
puts "#{key}'s grade is #{value}"
end 
        

Let's Develop It

Write a program that prints out every number between 1 and 1000 that is divisible by 7.


Hint: the modulo operator, %, will be helpful.

Methods

A method is a name for a chunk of code

Methods are often used to define reusable behavior.

Let's look at a method we've already used:


1.even?
=> false

"fred".capitalize
=> "Fred"
          

If you have some code you want to reuse or organize, methods will help.

Let's Develop It!

Find the methods available on String and Integer

Do they have any similar methods?


"abc".next
=> "abd"

"abz".next
=> "aca"

1.next
=> 2

-1.next
=> 0
  

Write a Method

Let's write a method together

def means define

subtract is the name of the method

x, y are parameters

x - y is the body of the method

x - y is also the return value


def subtract(x, y)
  x - y
end
        

Let's Develop It!

Let's write a method that takes in a number and tells us if it is even.

Hint: if number % 2 == 0, then it is even


          def method_name(parameter)
            # method implementation
          end
  

Method Return Value

Every Ruby method returns something.

Usually, it's the last statement in the method.

It could be the value sent to return if that came first.


def subtract(x,y)
  x - y
  'another thing'
end

return_value = subtract(5, 2)
puts return_value

def subtract(x,y)
  return x - y
  'another thing'
end

return_value = subtract(5, 2)
puts return_value
  

Arguments vs. Parameters

Technically speaking, arguments are passed and parameters are declared.

Note that the variable names don't have to match!

In this code, 5 is an argument and x is a parameter


            def subtract(x,y)
              x - y
            end

            subtract(5, 2)
  

Splat Arguments


def greet(greeting, *names)
  names.each do |name|
    puts "#{greeting}, #{name}!"
  end
end

>> greet("Hello", "Alice", "Bob", "Charlie")
Hello, Alice!
Hello, Bob!
Hello, Charlie!
  

Default Values


def eat(food = "chicken")
  puts "Yum, #{food}!"
end

>> eat
Yum, chicken!

>> eat "arugula"
Yum, arugula!
  

Default Hash Parameter


def add_to_x_and_y(amount, vals)
  x = vals[:x]
  y = vals[:y]
  x + y + amount
end

add_to_x_and_y(2, {:x => 1, :y => 2})
  

Named Parameters

To pass variable parameters, or to pass named parameters, you can use an options hash


def bake(name, options = {})
  flour = options[:flour] || "rye"
  creamer = options[:creamer] || "cream"
  puts "baking a nice #{flour} loaf with #{creamer}"
end

bake("Wheat")
bake("Sourdough", :flour => "sour")
bake("Pumpernickel", :creamer => "butter")
  

Methods & Variables

Local vars are only available in the methods where they were defined.


# Let's extract the length of the padded string into
# a local variable
def message(our_string)
  length = 80
  puts our_string.center(length, "-")
end

def different_message(some_string)
  puts our_string.center(length, "=")
end
# Error! 'our_string' and 'length' are not defined inside this method 
  

Objects

An Object is the building block of a program.

Objects do things and have properties.

Object: Number

What can it do?

  • Add
  • Subtract
  • Divide
  • Multiply
  • What are some properties of your Number?

  • Length
  • Base
  • Even

Object Class

Objects can be grouped by Class.

Classes define a template for objects. They describe what a certain type of object can do and what properties they have in common.

There are many kinds of objects, including String, Number, Array, Hash, Time, ...

To create an object we use .new


array = Array.new
          

'array' now refers to an object instance

Object Methods

Methods can be defined on objects.


array = Object.new

def array.delete
  puts "deleted the array"
end

array.methods(false)
        

Instance Variables

Represent object state

Names start with an @

Only visible inside the object


cookie = Object.new

def cookie.add_chips(num_chips)
  @chips = num_chips
end

def cookie.yummy?
  @chips > 100
end

cookie.add_chips(500)
cookie.yummy?   #=> true
        

Object Oriented Programming

  • Object Oriented Programming is one of many programming approaches: procedural, event-driven, functional, declarative...
  • These days, most programming is done in an OO language: Java, C#, C++.
  • All this means is that programs are organized around objects (data & methods).
  • You might choose OOP because Objects make things easier to understand and act as a natural way to modularize code. When a large code base is composed of many small Objects, it is easier to maintain and change.

OOP & Easy Understanding

Objects often take on names from their domain which makes them easy to conceptualize.

For example, without seeing my code, you can probably guess what an object called 'Bike' can do (or not do)

OOP & Encapsulation

One thing that makes code easier to maintain is Encapsulation which is one of the fundamentals of OOP.

Encapsulation is a nice way of saying 'put all my properties/behaviors in my capsule where other objects can't touch them'.

By assigning certain responsibilities to objects, code is more purposeful and less likely to be changed by accident.

OOP & Inheritance

Just as you inherited traits from your mom, your objects may inherit traits from other objects.

Inheritance is when you use one class as the basis for another.

You might use Inheritance if two objects have the same properties and methods. This way you don't need to write the same thing twice.


    class MyString < String
    end

    my_string = MyString.new
    my_string.upcase
  

OOP & Polymorphism

  • Similar to inherited traits and behaviors, there are also polymorphic traits and behaviors.
  • Polymorphic means many forms.
  • Within OOP, this relates to different objects being able to respond to the same message in different ways.

    [1, "abc"].each {|object| puts object.next}
  

Practice

Go to http://pine.fm/LearnToProgram/?Chapter=08


  • Scroll down to "One More Big Example", and make sure you understand what it is doing.
  • Copy and paste that program into a file and run it!

  • Try and make the change to the program according to the first bullet point under "A Few Things To Try"