Git Product home page Git Product logo

ruby-remembering-objects-readme's Introduction

Ruby Object Remembrance

Objectives

  1. Explain the concept of remembrance in object-oriented programming.
  2. Use class variables to remember, or store, instances of a class that are produced.

Introduction

Let's say we're building a command line game in which players play various rounds until a final tally determines the winner. Or creating an app in which we want to store a list of all of the users who sign up. Or building a program that helps users track and store the passwords for their various accounts.

In all of these situations, and many more we can imagine, our application needs a way to store or remember a collection of class instances. Whether they are instances of a Game, User or Password class, all of these examples would require our program to keep track of instances that are created.

Luckily for us, Ruby allows us to do so by using class variables to store new instances as soon as they are created. Let's take a look together.

Using class variables to store instances of a class

Imagine we are building an app that manages a user's music. Our app should keep track of all of the songs a user enters and allow our user to browse their existing songs.

Let's take a look at the following class:

class Song

  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

With this code, we can create a new song like this:

hotline_bling = Song.new("Hotline Bling")

Let's go ahead and create another song:

thriller = Song.new("Thriller")

Uh-oh. Our user wants to browse their songs now and select one to play. Currently, our code in the Song class has no way to keep track of the songs we just created and display them back to the user.

Creating the Class Variable

Let's take a step back and think about the concept of responsibility. Whose job is it to know about every instance of the Song class? We have two choices right now: an instance of the song class or the Song class itself.

It is not the responsibility of an individual song to know about all of the other songs. Keeping track of all of the songs that it creates, however, fits right into the purview of the Song class.

So, how can we tell the Song class to keep track of every instance that it creates? We use a class variable.

Let's create a class variable, @@all, that will store every instance of the Song class. Recall that @@ before a variable name is how we define a class variable.

class Song

  @@all = []

  attr_accessor :name

  def initialize(name)
    @name = name
  end
end

Notice that we set our class variable equal to an empty array. Arrays are perfect for storing lists of data, so we'll use an array to store our lists of Song instances.

Now that our class is set up to store the instances that it produces, we have to ask: how does it store these instances?

Adding Instances to the @@all Array

Before we can answer this question, we should ask another. When should the Song class become aware of, or store, an instance of itself?

This should happen at the time on instantiation––when a new song gets created, it should be immediately stored by our Song class' @@allclass variable.

We can implement this by simply adding the new instance that gets created into the array stored in @@all inside our #initialize method.

Let's take a look:

class Song

  @@all = []

  attr_accessor :name

  def initialize(name)
    @name = name
    @@all << self
  end
end

In #initialize we use the self keyword to refer to the new object that has just been created by #new. Remember that when #new is called, it creates a new instance of the class and then calls #initialize on that new instance. So, #initialize is technically an instance method. Inside an instance method we are in what is called method scope and self will refer to whichever instance the method is being called on.

We push self into the array that is stored in @@all. In this way, the @@all class variable will point to an ever-growing array that contains every instance of the Song class that gets created.

Our Code in Action

Let's see what happens when we actually execute the code we've written:

ninety_nine_problems = Song.new("99 Problems")
thriller = Song.new("Thriller")

Now that we've created some songs, let's ask our Song class to show us all of the instances that we just created:

Song.all
  => NoMethodError: undefined method 'all' for Song:Class

Uh-oh, looks like we don't have a class method to access the contents of the @@all array. Just like how we've built reader methods that expose the value of instance variables, we need to build a method that will expose, or make accessible outside of the class, the value of a class variable.

Let's build one now.

Building a Class Method to Access a Class Variable

Let's call our class method #all. All it needs to do is return the @@all variable. Remember that the last line of any method in Ruby is automatically returned. So simply putting @@all in self.all is that method's purpose.

class Song

  @@all = []

  attr_accessor :name

  def initialize(name)
    @name = name
    @@all << self
  end

  def self.all
    @@all
  end
end

Recall that to define a class method we use the def self.method_name syntax. The self. before the method name is a reminder that the method will not be running on a particular Song instance, but will be acting as the factory from which all Songs are made: the Song class.

With a new method defined, we can try again to call our class method on the Song class:

Song.all

This should output something like:

irb(main):020:0> Song.all
=> [#<Song:0x00007fd9910c45a0 @name="99 Problems">, #<Song:0x00007fd9900dba58 @name="Thriller">]

Building off of all

Implement a class method called print_all_song_names which prints out all the names of the Songs that the class knows about. Use the all class method and build off of it!

Conclusion

We did it! We used a class variable to store a collection of instances of that class. We added new instances to this storage container every time a new instance was created with the help of the self keyword in our #initialize method. Lastly, we wrote a class method to access and print out the name of each song instance stored in our class variable.

View Ruby Object Remembrance on Learn.co and start learning to code for free.

ruby-remembering-objects-readme's People

Contributors

alexgriff avatar annjohn avatar aviflombaum avatar franknowinski avatar gj avatar jakebrady5 avatar jmburges avatar maxwellbenton avatar sophiedebenedetto avatar victhevenot avatar ycohn avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby-remembering-objects-readme's Issues

Lessons out of order

I believe this remembering objects read me has information that would have been useful for the class variables and methods lab that is before this page. Just figured id put my 2 cents in! thanks!

`Song.all` is wrong

In this example Song.all is not exposing @@all but is rather printing song names, which would not make it a class reader.

Invalid variable name in example

There's a problem with the example that says, "With this code, we can create a new song like this:"

99_problems = Song.new("99 Problems")

The variable name can't start with a number. It should be named something like ninety_nine_problems.

Lesson Placement

Hey guys! This lesson would be extremely helpful to read before completing the Class Variables and Methods lab in the previous section. Consider moving it.

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.