Giter Club home page Giter Club logo

ruby-monster-oop's Introduction

Class-based Object Oriented Programming

Ruby heart's Object Oriented Programming

Why is this important?

This workshop is important because:

  • Ruby is designed for Object Oriented Programming with classes.
  • Class-based OOP is much more common across languages than JavaScript's prototype-based system - even JavaScript is adopting classes.
  • To understand more complex Ruby code (like Rails) one must be comfortable with classes.

What are the objectives?

After this workshop, developers will be able to:

  • Define the OOP terms “class,” “instance,” and “inheritance.”
  • Create your own classes and instances.
  • Define attributes and methods for instances or for the class as a whole.
  • Explain and implement the class-based inheritance pattern.

Where should we be now?

Before this workshop, developers should already be able to:

  • Describe how JavaScript handled Object Oriented Programming.
  • List two benefits of OOP.
  • Write methods in Ruby.

Review

Hashes

Hashes are simple key value stores. They look a lot like JavaScript's objects.

Hash Example:

 our_hash = {name: "Napoleon", fav_food: "steak", skills: ["archery", "combat", "egg farming"]}

 # => {:name=>"Napoleon", :fav_food=>"steak", :skills=>["archery", "combat", "egg farming"]}

The colon notation always results in your keys being symbols, which is usually what we want. The hash rocket notation gives you more control over the types of your keys.

Objects

Ruby also has Objects to organize methods and data. In fact, everything in Ruby is a BasicObject. However, we almost never use plain BasicObjects or Objects because there are more sophisticated, specialized classes such a String, Integer, and Hash.

Class Inheritance Tree:

Class inheritance

Example: How can we prove that the hash we just created is a BasicObject?

# there's a built-in method for that:
our_hash.is_a? BasicObject
# => true

OOP in JavaScript

Object Types with Constructor Function and Prototype

// constructor function sets up the type 
function Car(color, model, year){
  this.color = color;
  this.model = model;
  this.year = year;
  this.wheels = 4;
}

// instance methods usually defined on prototype
Car.prototype.repaint = function(newColor){
  this.color = newColor;
}

Classes and Modules (ES6)

// bring in Animal class from a different 'Animals' module
import Animal from 'animals'

// define Dog class
class Dog extends Animal {
  // constructor for initial behavior and state
  constructor (dogName="Good Dog") {
     this.name = dogName;
     this.sound = 'woof';
  }
  // instance method for the class
  speak () {
     console.log(`${this.name} says ${this.sound}!`);
  }
}

// an instance of Dog
let morocco = new Dog('Morocco');
morocco.speak();

// export 
export Dog

Classes and Ruby

Ruby uses classes for object-oriented programming. Classes are data types used to create more data. They are similar to the object types we manipulated with constructors and prototypes in JavaScript.

Classes are more common among programming languages than prototypes, so we'll go into more depth about OOP with Ruby than we did with JavaScript. This will help give us extra context for JavaScript classes from ES6, like we saw with React.

  1. Challenge: Create a Monster class in Ruby and an instance of Monster.

Hint: you'll have to use the Ruby reserved word class and the new method.

initialize

  1. Challenge Update the Monster class so that we see "Rawr!" when a monster is first initialized.

monster rawr gif

Instance Variables

What should we do if we want to set attributes on the monster, such as its habitat?

Since each monster will probably have a different habitat, this is a good candidate for an instance variable. Remember Ruby classes mark instance variables with @.

  1. Challenge: Add a habitat instance variable and any instance methods needed to your Monster class to enable this code...
rabbit = Monster.new
# Rawr
rabbit.habitat = "Cave of Caerbannog"
rabbit.habitat
# => "Cave of Caerbannog"

Hint: Use the methods attr_accessor, attr_reader, and/or attr_writer


  1. Challenge: Add a threat_level instance variable to the Monster class. Allow the user to specify a threat level when the monster is created.
dalek = Monster.new(:high)
dalek.threat_level
=> :high

Hint: use initialize


  1. Challenge: Allow the user to create an instance of Monster without specifying a threat level. The default threat level for a new monster should be :medium.
teletubby = Monster.new
teletubby.threat_level
=> :medium

Instance Methods

  1. Challenge: Create a habitat? instance method for Monster that tests whether the monster's habitat matches an argument that is passed in.
yeti = Monster.new
# Rawr!
yeti.habitat = "tundra"
yeti.habitat?("swamp")
# => false
yeti.habitat?("tundra")
# => true

Hint: use def to define a new method inside the class

Class Variables and Class Methods

What if I wanted a running count of all the Monsters ever created? Let's keep track with a class variable and print a message each time a new monster spawns.

  1. Challenge: Add a class variables to enable this code...
predator = Monster.new(:high)
# Rawr!
# 2 monsters now roam the world!
alien = Monster.new(:high)
# Rawr!
# 3 monsters now roam the world!

Hint: Create a class variable with @@


  1. Challenge: Create a class method to get the current value of the monster count.
Monster.count
# => 3

Hint: Use the reserved word self

Note: Class variables SHOULD BE AVOIDED due to their weird behavior with inheritance!

  1. Challenge: Add a check so that the allowed threat_level values at creation are:low, :medium, :high, or :midnight. If another value is passed in as the initial threat_level, raise a runtime error.
rubber_ducky = Monster.new(:friendly)
# /stretch.rb:31:in `initialize': cannot create monster - invalid threat level friendly (RuntimeError)

  1. Optional Constant Part 1: Create a class constant called THREAT_LEVELS that is an array containing all the allowed values of threat_level.

Hint: Access the class constant with Monster::THREAT_LEVELS.

Hint: Use freeze to make sure the value of THREAT_LEVELS isn't changed later (necessary for array constants).


  1. Challenge: Create a fight class method for Monster that takes in two monster instances and compares their threat_levels. The fight method should return the monster that has the higher threat level. If they're tied, let the second monster win.

  1. Optional Constant Part 2: Refactor fight to use index with the THREAT_LEVELS array. You should be able to make fight code shorter and simpler.

  1. Optional Constant Part 3: Include the Comparable mixin in your Monster class and create a custom <=> method to compare monsters based on their threat levels. Refactor fight to use this comparison.

  1. Compassion Challenge: Give your Monster class a name instance variable with a getter and a setter.

Hint: only modify initialize as a stretch (solution not provided). If you modify initialize so it takes a name argument, update your simple test code to give each monster instance a name. Wondering how you could make the name argument optional like threat_level? Look up Ruby's "keyword arguments" syntax.

monster

Quick Review

  • What is a class?
    • What is an attribute?
    • What is a method?
  • What is the difference between:
    • an instance variable
    • a class variable
  • What is the difference between:
    • an instance method
    • a class method
  • Why do we use classes?
  • Looking ahead: What is inheritance?

Head over to Part 2

ruby-monster-oop's People

Contributors

bgveenstra avatar tgaff avatar nathanallen avatar jlopker avatar justincastilla avatar cofauver avatar eerwitt avatar cameronjacoby avatar ben-manning avatar benhulan avatar nick-brennan avatar ajbraus avatar mtvillwock avatar zoejf avatar ilias-t avatar mnfmnfm avatar stanleyyork avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.