Episode 5a - Hashes Versus Classes

Let's use hashes to represent information about laptops.

laptop1 = { "brand" => "apple", "color" => "silver", "screen_size" => 13 }
laptop2 = { "brand" => "microsoft", "color" => "black", "screen_size" => 15 }

p laptop1
p laptop2

The code will output:

{"brand"=>"apple", "color"=>"silver", "screen_size"=>13}
{"brand"=>"microsoft", "color"=>"black", "screen_size"=>15}

To retrieve the brand of a laptop, you can use square brackets with the key name:

p laptop1["brand"]

The code will output:

"apple"

What would this code look like if we chose to use classes instead of hashes?

class Laptop
  def initialize(brand, color, screen_size)
    @brand = brand
    @color = color
    @screen_size = screen_size
  end
end

laptop3 = Laptop.new("apple", "silver", 13)
laptop4 = Laptop.new("microsoft", "black", 15)

p laptop3
p laptop4

The code will output:

#<Laptop:0x007ff312092a38 @brand="apple", @color="silver", @screen_size=13>
#<Laptop:0x007ff3120924e8 @brand="microsoft", @color="black", @screen_size=15>

If we want to retrieve the brand of a laptop, it's currently not going to work!

p laptop3["brand"]  # this won't work, since laptop3 is not a hash
p laptop3.brand # this won't work, because we haven't defined a method in our class called brand

To make this code work, we need to define the method in the class to allow someone to retrieve the brand:

class Laptop
  def initialize(brand, color, screen_size)
    @brand = brand
    @color = color
    @screen_size = screen_size
  end

  def brand
    @brand
  end
end

laptop3 = Laptop.new("apple", "silver", 13)
laptop4 = Laptop.new("microsoft", "black", 15)

p laptop3
p laptop4

Now you can write this code that works!

p laptop3.brand # this will work now!

The code will output:

"apple"

Even though this makes it seem like using hashes is much better than using classes, this is actually one of the benefits of using classes! You as a programmer have more control over what things can be done with an instance. You will see much more of this as you work with Ruby and more complex data.

Exercises:

  1. Rewrite the two hashes to use a class instead (similar to the example above):
    shirt1 = { "type" => "short-sleeve", "price" => 12 }
    shirt1 = { "type" => "long-sleeve", "price" => 18 }
    
    class Shirt
      # your code goes here!
    end
    
    shirt3 = Shirt.new("short-sleeve", 12)
    shirt4 = Shirt.new("long-sleeve", 18)
    
    p shirt3
    p shirt4
    The code should output:
    #<Shirt:0x007fe7f3894738 @type="short-sleeve", @price=12>
    #<Shirt:0x007fe7f3894490 @type="long-sleeve", @price=18>
  2. Rewrite the three hashes to use a class instead. Also write the method in the class to allow someone to retrieve the birthplace:
    actor1 = { "name" => "Keanu Reeves", "birthplace" => "Beirut, Lebanon"  }
    actor2 = { "name" => "Meryl Streep", "birthplace" => "Summit, NJ"  }
    actor3 = { "name" => "Jack Nicholson", "birthplace" => "Neptune City, NJ"  }
    
    class Actor
      # your code goes here!
    end
    
    actor4 = Actor.new("Keanu Reeves", "Beirut, Lebanon")
    actor5 = Actor.new("Meryl Streep", "Summit, NJ")
    actor6 = Actor.new("Jack Nicholson", "Neptune City, NJ")
    
    p actor4
    p actor5
    p actor6
    
    p actor4.birthplace
    The code should output:
    #<Actor:0x007ffdca871cc8 @name="Keanu Reeves", @birthplace="Beirut, Lebanon">
    #<Actor:0x007ffdca8712a0 @name="Meryl Streep", @birthplace="Summit, NJ">
    #<Actor:0x007ffdca870d00 @name="Jack Nicholson", @birthplace="Neptune City, NJ">
    "Beirut, Lebanon"
  3. Rewrite the two hashes to use a class instead. Also write the methods to retrieve the name and the color, and another method to redefine the color.:
    boat1 = { "name" => "S. S. Minnow", "color" => "white", "price" => 20000 }
    boat2 = { "name" => "Titanic", "color" => "black", "price" => 700000000 }
    
    class Boat
      # your code goes here!
    end
    
    boat1 = Boat.new("S. S. Minnow", "white", 20000 )
    boat2 = Boat.new("Titanic", "black", 700000000)
    
    p boat1
    p boat2
    
    p boat1.name
    boat2.color = "red"
    p boat2.color
    The code should output:
    #<Boat:0x007fbe9b069b98 @name="S. S. Minnow", @color="white", @price=20000>
    #<Boat:0x007fbe9b069878 @name="Titanic", @color="black", @price=700000000>
    "S. S. Minnow"
    "red"