Sign In | Subscribe
Start learning today, and be successful in your academic & professional career. Start Today!
Loading video...
This is a quick preview of the lesson. For full access, please Log In or Sign up.
For more information, please see full course syllabus of Introduction to Ruby
  • Discussion

  • Study Guides

  • Download Lecture Slides

  • Table of Contents

  • Transcription

  • Related Services

Bookmark and Share

Start Learning Now

Our free lessons will get you started (Adobe Flash® required).
Get immediate access to our entire library.

Sign up for Educator.com

Membership Overview

  • Unlimited access to our entire library of courses.
  • Search and jump to exactly what you want to learn.
  • *Ask questions and get answers from the community and our teachers!
  • Practice questions with step-by-step solutions.
  • Download lesson files for programming and software training practice.
  • Track your course viewing progress.
  • Download lecture slides for taking notes.
  • Learn at your own pace... anytime, anywhere!

Classes: Part III

  • A class variable is visible and shared by class definitions, class methods, and instance methods of that class
  • It is not visible to instances of that class
  • A class instance variable is associated with the class rather than the instance of the class
  • It is more similar to a class variable than an instance variable
  • also known as the "instance variables of class objects"
  • It is used to subclass an existing class
  • There are three types of method visibility: public, private, or protected
  • Methods default to public except for the initialize method
  • public methods can be invoked anywhere
  • private methods can only be invoked by other methods of the class
  • protected methods can be invoked from within its class or its subclasses
  • Instance and class variables are essentially private
  • Constants are public
  • Subclassing allows the creation of a new class based on, but modified from, behavior of an existing class
  • A class can extend another class where the child is called the "subclass" and the parent is called the "superclass"
  • Inheritance allows a class to have the same features of another class above it
  • The class "inherits" those features
  • A class may "extend" or "inherit from" another class known as the superclass
  • To extend a class,add "<" and the superclass to the class statement
  • Subclassing allows you to override an existing method
  • Chaining allows you to augment behavior of an existing method
  • keyword super allows the chaining process to occur
  • super invokes a method with the same name in the superclass of the current class or an ancestor
  • Arguments can be passed to it
  • The Singleton Pattern is a class that can only have a single instance
  • Use the "instance" method provided to access it

Classes: Part III

Lecture Slides are screen-captured images of important points in the lecture. Students can download and print out these lecture slide images to do practice problems as well as take notes while watching the lecture.

  • Intro 0:00
  • Class Variables 0:14
    • Example
    • Ruby Glass Jar Example
  • Class Instance Variables 10:20
    • Instance variables of class objects
    • Advantage of class instance variables
    • Examples
  • Method Visibility 16:16
    • Three types of method visibility
    • Public methods
    • Private methods
    • Protected methods
  • Invoking Method Visibility 19:21
    • Public , Protected, and Private Visibility
    • Invoking Method Visibility With Arguments
    • Example: Invoking Method Visibility
  • Class Visibility 23:31
    • Instance and Class Variables are Private
    • Constants are Public
    • Makes Existing Class Methods Private
    • Makes Existing Class Methods Public
    • Example: Class Visibility and class GlassJar
  • Subclassing 27:08
    • Subclassing: Subclass and Superclass
    • Example: Subclassing
  • Inheritance 30:05
    • Inheritance
    • Example: Inheritance
  • Subclassing and Inheritance 31:34
    • Descendants
    • Ancestors
    • More On Descendants and Ancestors
  • Extending a Class 33:27
    • Extending a Class
    • Coding Example: Extending a Class
  • Overriding a Method 36:41
    • Overriding a Method
    • Coding Example: Overriding a Method
  • Modifying Methods with Chaining 38:52
    • Modifying Methods with Chaining
    • Super
    • Coding Example: Modifying Methods with Chaining
  • The Singleton Pattern 44:52
    • Introduction to The Singleton Pattern
    • Setting Up Singleton
    • The Instance Method
    • Rdoc for Singleton: Usage
    • Rdoc for Singleton: Implementation
    • Coding Example: Singleton

Transcription: Classes: Part III

Welcome back to Educator.com.0000

Today's lesson is on classes; this is Part 3.0002

The first thing we're going to go over is class variables.0010

This is pretty important; you will see many variations of variables in this lesson, and some of them are for instances of classes, and some are just classes.0014

This is class variables; these are the visibility to them; we really want to know what can see it and what can't.0028

It's visible and it's shared by class definitions, class methods, and instance methods of that class.0037

That is very interesting; you can see it in instance methods.0045

By any other language, you would say the same--I can see it in class definitions; I can see it in class methods; but note that it's not visible to instances of that class.0051

If you're using it in an instance of the class, in that one, you're not going to see visibility.0066

How to implement this: the names must begin with this @@; this will create your class variable.0073

I have a little example here: I created this class called GlassJar.0087

Here you see that there are actually four class variables here, so here is an example of those class variables.0096

I have this class variable coins, gummyworms, marbles, rubberbands; and I initialize them all to 0.0105

Let's go to a deeper example, because I have other code that I want to put here, and I have it in another example here.0117

Let's look at my file here: it's called the GlassJar.0132

You will notice that, at the top, I have those class variables: coins, gummyworms, marbles, rubberbands--all set to 0.0135

Then you can see that we have the initialize method to help us create our new instance.0149

It takes one parameter; it takes a Hash; by default, if you don't put anything in there, it's going to make a default empty Hash, items=empty Hash.0160

We're going to initialize first our own local variables, and then we're going to store that into our class variable.0174

These class variables are very interesting, because it is shared amongst the classes.0183

You will see these values you set, and you will see it continue to hold its value as you use it more and more.0189

Let me show you an example.0200

First, for this example, we're going to initialize all of these local variables.0201

Then, I want to say, "OK, in this coins variable, I'm using this ternary operator," and it says, "If coins is nil--if I don't pass in coins in this has--default coins to 0; else, I want you to give me the length of those coins.0208

In this initialize, I'm asking--for these coins, the gummyworms, the marbles, the rubberbands--I'm asking the number of those that are in this jar.0227

For this example, you will notice that there is also a += ; I'm going to continue incrementing that, so if someone creates a new GlassJar that has five coins, and then I create another GlassJar that has ten coins, this class variable is going to say 15, and we will validate if that is true.0239

Exactly the same with the gummyworms, marbles, and rubberbands; I use this ternary operator, and I'm taking this Hash with the symbol; again, if it's nil, it's just going to do 0--it's not going to add anything to it.0262

If you pass in a number greater than 0, we're going to add that in.0279

There I have my initialized method, and I have my class variables being set and added to, whenever this new instance is created.0283

Then, I have this other method; this is a class method, so we have our class method.0299

It's called totals, and all it does is just to report the total number of items.0308

It's going to look at all of these class variables and say, "Hey, here's the total number of coins you have in all your jars; how many gummyworms--the total amount in the jars? Total amount of marbles and rubberbands?"0314

I do some interpolation here; I have the class variable set inside for each of them, and it's going to output this out.0326

After we have this class done, we want to set some of these objects up and report the total.0338

For the first one, I have this Hash; we have coins, and I pass an Array in, so it's going to take this Array, and it's going to change that to a length so it can aggregate this data.0349

I don't care about what kind coin it is for the class variable--only for that instance object.0366

For this example, you will notice it says coins; it sets a quarter in there, and then we have another element in that Hash called marbles, and it puts an Array of two marbles, blue and green.0375

When I call this GlassJar.totals, I should be able to see: coins should have a 1, and marbles should be 2.0394

Here, I set that whole object into a local variable called G, so I just put the output puts G, so we can see the output when you run this code.0410

For the next one, I have another variable called H; what I do here is...I'm actually creating another GlassJar object; in this version, I have two coins; I have a dime and a nickel, so that's two coins; and we have one rubberband--it's an orange rubberband.0420

When I call this coins total, this GlassJar total, you see the coins--it's pertaining to aggregate, so we have two coins here, and in the past one we had one coin; so it's going to be a total of three coins.0441

Then, we don't have any rubberbands here--well, we have one rubberband, but we don't have any marbles here.0461

But, we did in the past one, so it's going to continue to aggregate it, so we're going to have marbles: 2.0470

And we have that one rubberband, so that has a length of 1.0475

So, we have one coin and two marbles; on the second run, we added two coins and one rubberband; so, we have three coins, two marbles, and one rubberband.0481

For my last object, I set it to value I, and I added a gummyworm into it, so it's going to have the exact same totals, but a gummyworm, too.0492

At the end result, we should have 3 coins, 2 marbles, 1 rubberband, and 1 gummyworm.0502

Let's go ahead and run this and see what output we get from it.0518

What I do is run Ruby, GlassJar, 1--that's the example we're going to look at--and you will notice, what I did is, I organized it by the value for each of the objects.0529

For the first one, we have that local variable G with the first value, so we get 1 coin, 2 marbles--we didn't say any gummyworms or rubberbands.0542

Then, for the second object, we take the aggregate of these two new objects; so, the coins total to 3; the marbles total to 2; and we have that new rubberband that we put in, so we have 1 rubberband, that orange one.0553

Then, our third object down--we just added that gummyworm, so we have 3 coins, 1 gummyworm, 2 marbles, 1 rubberband.0567

This is pretty powerful; we have different instances, but we have these class variables that are shared between the instances, and we can access them.0575

But notice that this isn't being called an instance method; it doesn't have access to that; it only has access to these if you use a class method, so you have to use a class method to get that visibility to use these class variables.0589

The next thing we're going to look at is class instance variables.0615

This might get pretty confusing: it's not an instance variable; it's not a class variable; it's called a class instance variable--leaning more toward the class side, though.0619

When I say that--it's more similar to a class variable than to an instance variable.0630

It's associated with the class, rather than the instance of the class.0638

The best way I like to put it is, with the number 3 here, it's instance variables of class objects.0644

You have your class objects--this is your instance variable.0652

It also may get confused with instance variables; the reason is that the syntax is the same.0658

So, what you would see in an instance variable looks just like a class instance variable.0669

What is the reason we use these class instance variables? You can subclass an existing class.0677

Let's go ahead and look a little deeper into how this is used.0683

Here I have class instance variables, and we're just going to use the exact same example we did in our first one, but in this case, we're going to do class instance variables in its place.0688

Notice, we're just using an @ sign; there are no two @'s.0699

This is that class instance variable.0705

We're just setting it to zero like we did before.0712

Let's go ahead and look at an example, so you can see some more of that code that goes right below here.0715

I have an example; it's just called GlassJar2; it does the exact same thing as the first code example we were looking at.0727

You have your class instance variables; they're all set to zero; let's look at our initialize method.0737

This constructor is interesting, because we're defining the initialize, but, since we can't use that class instance variable here, we have to actually set it up in self.new, which is a class method, so it allows us to do that.0743

First, we look at initialize; it's very simple.0763

You take this Hash of items, and we're just storing it to local variables: coins=items(coins), gummyworms=items(gummyworms), marbles, rubberbands...0767

That is not really relevant, so we should probably actually set these to instance variables, just so they could be used now; because, if I set them as local, it's not going to be used anywhere; but for our case and purpose, we're not worrying about that, because we'll implement that instance method later for whatever purpose we need to.0779

Getting back to the example: we have these class instance variables: what is important is this self.new method here.0800

We have a class method that allows us to initialize the class instance variable.0810

Here, we have @coins, and we're just doing the exact same thing we did in the other example; it's going to take that Array and check the link.0817

If it's nil, it's going to be zero; if there is an Array of coins in there, it will get the link, and it will store that in here.0829

It also has a += ; so it's keeping this total account, so it can continually add it in and utilize it as an aggregate as all of these GlassJars--and we do that with marbles, gummyworms, and rubberbands.0837

Again, we still have that same class method here with self.totals; it takes the total number of coins; the only difference is--look here--we're using instance variables in here, but remember, this is getting that class instance variable.0855

It's kind of confusing, but just think of it as, if I'm using this class method, it's going to grab that class instance variable.0872

It doesn't have access to those normal instance variables.0879

Gummyworms, marbles, rubberbands...it's just going to output the same thing.0883

We'll see that again.0887

We have our example here; again, let's go ahead and add them up: we have coins, which is going to be one coin; two marbles; and for our H object, we have two coins, so that's going to make it coins-3; we still have 2 marbles; and one rubberband.0891

Then, for our last one, we just add that gummyworm in.0913

That is the only new thing that's in here; so let's go ahead and take a look at that.0918

Let's have this run and see if it has a similar output; we have 1,2,3,2,1,3,1,2,1; I'm going to clear it and just do number 2, which is the code we just saw.0932

They do look exactly the same; so, we've used class variables and class instance variables, and we were able to mimic the exact same logic we've been doing here.0946

That is class instance variables; let's get away a little bit from variables and look a little bit more at method visibility.0970

You have three types of method visibility for instance methods; we're looking at instance method visibility here.0980

They have three types: they have public, private, and protected.0993

Depending on what visibility, you can access it from different places; you have different scopes.1001

How does it call this public/private/protected? These are instances that belong as part of the module class.1009

From all the different code you've already seen in the past, we haven't called protect and we haven't called private, so by default, they go to public--so automatically, they default to public.1020

There is one exception--that initialize method; that one is always private.1034

That is why you have to call that new method; you can't call initialize.1046

Let's look at those again; number 1, we have that public method that can be invoked from anywhere; number 2, for private methods--private methods can only be invoked by other methods of that class.1053

That's interesting; I can't just go and make this new instance variable and just call it from its reference; only methods inside that class have access to these private methods.1070

Number 3, protected methods, can be invoked from within its class or its subclasses; so protected method gives it a bit more flexibility; not only can my own methods call it, but subclasses of it can call it, too.1086

By the amount of visibility--let's say here we have greatest visibility vs. least visibility--you would see that public has the greatest visibility, and then protected, and then private.1106

In this trend, least visibility to greatest visibility...1155

Let's look at how I use these methods; I just stated what they do; let's see it in some real code.1164

If public, private, or protected is called without arguments, all subsequent methods below it will have the specified visibility.1174

This is very simple; if I just call this method, what it means is, I call it, and anything below that is going to be that visibility.1185

First, let's look at this example here with this GlassJar.1196

If I don't call any of these methods, it's going to default to public visibility, so all this part is public.1201

The next thing, I call this method called protected; again, I call it without any arguments, and any code below this is going to have protected visibility to it.1214

The last one, just like I said before--I call private; anything below that will have private visibility.1240

It overrides; as long as I put a new method there, it's going to override and take precedence to whatever was in the past.1248

So, all of this is going to have private visibility.1257

Now, I didn't actually include any code here, but all this stuff is where your code would be, and all of it will have that scope; so, if it's private, all of these methods will be only accessible by other methods that are inside this whole class.1265

Public and protected, as well--of course, they have access to these classes.1295

Now, let's look at invoking method visibility, but this time, what if we include arguments--how do you do it with arguments?1300

First, with arguments, they alter the visibility of the method.1308

The argument being passed is the name of the method in the form of a symbol or string.1315

What argument am I passing? I'm passing the argument as the name of the method; that's the key part here--that name of the method.1323

Let's look at an example; we have this GlassJar; we have three methods: one processes marbles, one processes rubberbands, and one erases all values from that jar.1334

By default, these are all public; but notice, right down here, we actually have these methods, and we have that argument; so we have protected, and then we call process_marbles; so this is our first argument; and then we have another one that says process_rubberbands, and this is our second argument.1347

It's under protected, so both of these are protected methods.1379

Then, this last one, we called private--so only methods in this class have access to this, to erase all items.1391

This one is private.1401

We looked at method visibility with those instance methods; let's look at class visibility.1412

We're going to look at variables, constants, and methods; let's look at the whole range of them.1424

First, instance variables and class variables are essentially private; they can only be called within that class itself.1432

Constants are public; if you wanted to access a public--we've seen in the past--it's very easy: you call the object with a ::, and then you have pi--this is public; it's very simple to call; it's open outside the scope of that class.1442

Now, let's look at changing the visibility of the class methods.1469

For the first one, you can change the class method to be private; so you just call private_class_method; it takes one argument--that's the method name.1475

This makes that existing class method private; and the argument, remember, is passed as a symbol--that is important.1500

The next one--let's say you have a private class method; you can turn it into a public class method.1509

You probably won't use this too often, but we should talk about it, still.1513

We have this public_class_method; it takes, again, that one argument--that method name; it makes existing class methods public, and the argument is passed as a symbol1518

By default, class methods are public; so you would have to make it private before public, and then call this again, so you wouldn't use it too often.1532

Let's look at an example here.1545

Again, let's continue with the GlassJar; you understand what we're doing here.1548

For the first one here, we have a class method, and it says to collect all items: it's going to grab all items--you give it a bunch of jars, and it's going to collect all the items and total everything up.1552

Then, what we do is--this is our class method, but we say, "Hey, we don't want access; we don't want people to have access to this; they're looking at our object here; I don't even want access in that class."1577

So, I can call private_class_method; stick in collect_all_items, which is that class method here; pass it in; and now, you've privatized that method--it's private now.1586

Normally, we could call that--so I call GlassJar.collect_all_items--now it will say NoMethodError; this is a private method; I'm not going to allow you to have accessibility to it.1608

Let's next look at subclassing; we're going to talk about that and then talk about inheritance; in Ruby, you will see that they are very similar--they're different terminology, but we're going to go over both of them here.1629

First, subclassing allows the creation of a new class based on, but also modified from, the behavior of an existing class.1647

This allows me to extend the functionality and modify reused code, but I don't have to repeat myself, which is nice.1662

This class can extend another class, where the child is called a subclass and the parent is called the superclass.1672

This is important, because we are going to use this terminology coming up.1681

I have class A, which is a parent, and class B, which is the child; the parent here is called the superclass, and the subclass is class B; the child is called the subclass.1684

Remember, this child extends this behavior of the parent to it.1718

A class can have a number of subclasses; in this case, child has a subclass from the parent.1729

Every class has a single superclass except BasicObject; BasicObject, if I asked it, "What is your superclass?", would say nil.1740

Remember, with this superclass, I can call it on any object; I can call Math and say, "Give me your superclass," and it will tell that to me.1749

Then, I can call the next object from that and call its superclass; eventually, it's going to hit BasicObject, and when you call BasicObject.superclass, you're going to get nil, because it doesn't have a parent class to that--that is the last one.1760

Again, here we have an example with the GlassJar.1784

We might call extends--GlassJar extends class Jar--so GlassJar is the subclass; Jar is the superclass.1789

Let's look at inheritance now that we've talked about subclass/superclass, child, which extends parent...1807

Inheritance allows a class to have the same features of another class above it; that class inherits those features.1820

Now, we can say that, in this case, child inherits parent.1827

The parent methods get inherited by the child.1842

We said they extend in the subclass; a class also--here we go--may extend or inherit from another class known as the superclass.1847

So, class may extend--we said that about subclassing--now you can use that inheritance, or inherit from the class known as the superclass.1858

Every class inherits directly or indirectly from the Object class.1868

Now, this Object class--if I call its superclass, that will be that BasicObject.1874

Object inherits from BasicObject class, just as I said.1881

From the previous example, class GlassJar inherits from class Jar.1886

So, let's bring it all together; you have subclassing and inheritance.1896

Descendants are the subclasses of a class, so that's descendants--and they are subclasses of the subclasses, so all these are called descendants.1902

Now, if I want to look at ancestors, ancestors of a class are the superclass, plus the superclass of the superclass, up to the Object.1916

Again, let's say, looking at Math, I look at one of its superclasses--Object.1928

Then I look at another superclass; I look at BasicObject.1938

What this says is that, for this object, anything above it is called the ancestor; so if we're looking at Object here--here is our scope; we're looking at Object; anything above is an ancestor; any things below it are called descendants.1946

What other descendants do we have that are objects? 1969

We have Array; we have String; we have Math; we have Hash; the reason is that all of these objects have a superclass of Object.1973

So, these are all now descendants of the Object, as well.1989

But, changing your scope--as if I were looking at Math, Array, String, or Hash, and I want to know what its ancestor is--BasicObject or Object; both are ancestors of it.1994

Now that we have that terminology down, let's look at how I extend a class.2008

It's fairly simple; to extend a class, all you have to do is add this < sign, and how you do that is you append that to the class name.2016

You append this and the superclass to the class statement; here is how you do it, right here.2030

So, what we are saying is that GlassJar extends Jar.2039

Also, GlassJar is a subclass of Jar.2054

The best way to see it is code that is in action, so let's go ahead and throw up our IRB...our Ruby terminal.2064

Let's go ahead and create some code; let's show an example of how this inheritance is working.2075

First, I'm going to define this Jar; I'm just going to say, "Hey, tell me what class I am--when I call this to_s object, I just want you to tell me what type of Jar I am."2080

The reason is...self.class will print you Jar; but when I call this GlassJar, I'm extending Jar, but I'm not actually defining that to_s method.2097

Let's see what it outputs; so first, I'm going to just initialize that Jar object, and I just call the class...2112

OK, that makes sense; we have a class that's Jar here; but now, let's see if I did GlassJar.2120

I call class on that; notice, when I call new, it tells me the Jar, and the type is GlassJar; I can also just call the to_s method right away, so you can compare.2140

We see inheritance working here; we extended the Jar object and actually used that method from the parent, and extended it so GlassJar has this to_s also.2155

OK, it inherited from that object; but let's see more of this inheritance.2170

First, we call to_s; we have that GlassJar; to_s; we have Jar; and let's look at it at a different angle.2183

Let's see if we defined it further--so let's look at some other examples to show this.2193

We talked about extending a class, and next I want to show you an example of code where we override this method.2200

To do this, we're going to look at a method called type.2208

Here, we're going to override a method; this subclassing that we just showed you allows you to modify an existing method, too.2211

We have this Jar; we're going to have this new method called type.2222

If I just call type and Jar, I want it to return generic; this is a generic jar; I don't know what type--what material--it is.2228

But with this GlassJar, when I call type, I want it to return glass.2234

Let's see it...I'm going to exit and run it again to clear the logic in there.2241

First, I'm going to just call GlassJar; I'm going to do type; notice, I'm doing everything in that one-liner syntax--it shortens it up; I don't have to put in three lines.2249

Then, I call GlassJar extends Jar; now, if I go to Jar.new and I call the type, it gets me generic.2262

If I call GlassJar.new and call type, notice it also calls generic; OK, it inherited, but I want to override that method, so let's show you an example of override now.2273

Now, I'm going to call GlassJar, redefining the class object.2287

I'm going to put type here, and I'm going to pass glass in there; so now, when I call GlassJar.new and do type, notice it says the type is glass.2292

Now, we have just overridden the pass method in our subclass.2309

So, we have that power to do that.2317

Let's move on from here; let's look at chaining; that is the next thing we want to look at.2330

What chaining allows you to do is, if I'm looking at a method, I can actually add on to that method--keep the existing one, but add on.2340

Instead of overriding the method, chaining allows you to augment the behavior of an existing method by adding code.2351

The keyword super allows the chaining process to occur.2360

What super is is this method that invokes a method with the same name in the superclass of the current class or an ancestor.2366

This super method--sometimes you will see it with arguments, sometimes not; it depends what is being initialized and what the superclass requires.2376

Arguments can be passed to it, if necessary, by the superclass.2388

Let's look at an example for that.2393

I'm going to start my IRB again; so, for this one, I'm going to create a Jar; I'm going to put some attributes here this time--so I'm going to have some marbles and rubberbands.2402

I'm going to have my initialize method now; it's going to require marbles and rubberbands; and we're going to set some instance variables here.2416

We have our Jar object; now we want to do our GlassJar; this one is going to say, "OK, you have marbles and rubberbands, but I'm actually going to initialize mine, so this can take pens, too."2433

Hold on; I made a little mistake--I'm supposed to actually have my subclass to Jar; then I'm going to call pens; because then, it knows, when I call super, who is its parent; the parent is the Jar.2454

I do attribute pens, I call my initialize, and notice that my initialize--I'm actually using three arguments; I have marbles, rubberbands, and pens.2467

All I'm going to do is to call super; so, for marbles and rubberbands, I already had passed functionality--my parent already knows how to set these values for me concerning my object.2480

So, I'm just going to call super and let it handle it; it already knows how.2491

Since it doesn't know how to handle pens, though, I'll set that myself.2495

It says there that we have superclass mismatch for GlassJar; let's see how we can fix that; for the first one, we may have redefined it; when we extend it to Jar, it says superclass mismatch.2503

Let's set that up again, so we start on a clean slate; I think what happened was that I set that initially without it, and it influenced that class.2546

I'm doing the attribute marbles and rubberbands...I'm going to do initialize marbles and rubberbands...marbles=marbles, rubberbands=rubberbands...OK.2559

Now, I'm going to call GlassJar and extend Jar; and here we have our pens; call our initialize, marbles, rubberbands...and we have pens now...2578

I'm just going to call super; it knows how to handle these--I don't need to worry about it...but you know what? I'm going to set those pens and...2592

OK, so we're good now; we solved that issue.2603

Now, first, I'm going to initialize that Jar object; I'm going to put a number that tells me how many marbles and rubberbands; I'm going to do 5 and 4.2608

Here we have our Jar object: 5 marbles, 4 rubberbands.2618

Now, let's look at GlassJar; I'm going to call GlassJar.new, and I'm going to call 1,2,3; that is three arguments, so that says I have 1 marble, 2 rubberbands, and 3 pens, and it sets those here.2629

Also notice, it did that super method; it got it from the Jar--we don't have to handle it there.2645

If I call marbles, it has 1; rubberbands has 2; I'm going to call pens, and it has 3.2652

What if I do pens in Jar?--remember, Jar doesn't know how to handle pens; this Jar doesn't have the capability; only that GlassJar does--so pens doesn't work.2664

Rubberbands works fine, and marbles work fine.2677

That is our chaining.2690

The last thing we want to look at is the singleton pattern.2694

The singleton pattern is a class that can only have a single instance.2702

It's interesting: we have this class, and it's only going to have one single instance.2714

If I create any others, it won't allow me to; I can only have one instance.2719

There is a special way to implement it: Ruby has a singleton method that implements it.2722

So, you have to make sure the module is loaded; to set it up, you have to run require 'singleton'; then you have to include singleton in whatever class you're doing--so that's include Singleton; and then you need to define and initialize method for the single instance of that class.2728

Then, all you would do is, after it is all completed and set up, you would set up 1,2,3; whenever you access this method, you have to use instance; you have to call instance provided by the module to access the class.2752

Let's say I have my object; I would have to call instance and then whatever method I have after that.2766

Let's go ahead and look at the RDoc for this.2784

Here, look at the RubyDoc; here it says that "the Singleton module implements the Singleton pattern"; to use it...let's look at an example.2789

I have this class; first I have to include that 'singleton'; then, when I call it to get the instance, all I do is to run Class.instance, and it's going to get me that class.2803

Look, they actually did == , and it says it's true.2818

Notice, if you do Class.new, it's going to give us this NoMethodError.2822

This new is private, so it's not going to allow it, because it's using the singleton pattern.2827

"The instance is created at upon the first call of Klass.instance."2836

Once you call that, then it's going to create it; notice, you call the instance, and then the object space has an increase of 1 of value to it.2842

The actual code from this RubyDoc is pretty slim, but it gives you a lot of knowledge of how the Ruby module has set up this singleton pattern.2855

How is this achieved? If you were to do this yourself, without doing include Singleton, you would have to make that Class.new and Class.locate private; you would have to override Class.inherit, Class.clone...2867

So, to insure that these singleton values are kept when inherited, and when they're cloned it would be the same instance, you would have to provide that class instance method that returns the same object each time it is called.2881

You would have to override the load to call Class.instance, and you would have to override that clone and dup, too--you don't want them creating new objects of this, so "raise TypeErrors to prevent cloning or duping."2893

By default, "#_dump...returns the empty string"; "marshalling, by default, will strip state information"; "classes using Singleton can provide custom _load...and _dump...methods to retain some of the previous state of the instance."2909

So, you see, here is the example; you have to run that require at the top; you have to include Singleton; and then, you notice, they call the _dump and _load here.2926

Then, you can call instance, and then you can run some methods.2938

Notice, they have some accessors--keep, strip--they can run those here, set those values...2944

They use Marshal.load, so you can dump a state into a local variable and load that back in.2950

You can also look at the class methods to see how it does that.2961

Now, let's look at our own example using the Jars.2979

Again, first, let's look at implementing this; so first, we have step 1, to make sure you require the 'singleton'.2986

If you're using a framework, you might have to initialize it beforehand; whatever is best.2996

This code will require that right here--I'm running IRB--to include that Singleton.3001

3: You set that initialize method up.3011

So, we have 1, 2, 3 steps here; we have the Singleton module loaded; we can include that in here; so now, we've included the module; we loaded the module; and third, we set up the initialize method for this instance.3015

When they call this instance one--when I call instance--it's going to set this up, and it's going to set marbles, rubberbands, and pens to 0--all of them to 0.3048

I do use these commas to keep it on one line.3061

Then, what we're going to do for this object...we're going to have this add method, and it's going to allow us to continually add as we get more marbles, rubberbands, pens; add it into our instance object here.3065

It takes one argument; marbles, rubberbands, pens default to 0.3088

If we do place a number in there, even with 0, it will add them into the totals.3093

Just like our previous slides, we're going to have something that does the total items.3103

Here, we call marbles, and it's going to show me how many marbles I have; rubberbands--it's going to show me how many rubberbands I have; and pens--it will show me how many pens I have in there.3110

Let's go ahead and run some code that has this.3123

I think I have it here in Jar.totals...3133

OK, here is our code; we load our Singleton, include it, have our initialize; we have add--we talked about total items...3137

I'm going to run this file; it's going to run some things: first, it's going to call this Jars.instance, total items. 3152

First run--it's going to create this object...set it to 0; it's going to return it to total items.3161

We haven't set anything in here yet, so this is just going to get 0 for all of them.3168

Then, I call this add; it's going to add a marble, a rubberband, and a pen; when I call this totals, I should get marbles: 1, rubberbands: 1, pens: 1.3173

Then, when I add 2, 3, 4, this is going to aggregate them together, so we have 3 marbles, 4 rubberband, and 5 pens.3187

I just commented on the side, so it's not going to actually affect the code.3204

I call Jar.totals, and you notice here that it does do it: we all start with 0; then 1,1,1; then 3,4,5.3209

That is the singleton pattern; that is the last thing I wanted to go over in this lesson on classes.3222

I hope you enjoyed it, and see you next time at Educator.com!3231