[MUSIC] I want to continue studying objects and class definitions by showing you how objects can have their own state. So the thing about an object's state, is that the state starts when you create the object. Every time you call the method, you can use the state, you can change the state, you can add to the state. It persists across the entire objects lifetime, now that state is only accessible by calling methods on the object. It's private to the object, only methods of the object can access that state. So with that background understanding let's get to the details about how you actually read and write the state. The state is just the collection of variables which we will call instance variables in which a lot of object oriented programming languages call fields. So if you see in Java or C# or C++, we're talking about fields here and all you do to create a field is assign to a variable that starts with the @ character. So if some method of an object says @foo equals 34, then that object's @foo instance variable is 34. And later in that method or in a later call to a different method on the same object, we can read @foo and we'll get 34. So we just assigned to something, and it springs into being, so we didn't have to say what the instance variables are. You have to be careful here, because if you meant @foo and you say @food or something else, you're just talking about a different instance variable. You can have as many as you want and they just come into existence as soon as you use them. In fact, if you use one that has never been assigned to for that object then you would think you would get an error, right? Accessing an undefined instance variable but instead you get a special object in Ruby called the nil object, which is vaguely similar to things like null in the other languages. But is actually an object and we'll have more to say about that in the future. Now that we have different objects that have different mutable state, we have to be curious about aliasing. As soon as you have mutation, aliasing matters in any programming language. So let me tell you the aliasing story in Ruby. When you create an object by using new, you get back a new object that is distinct from all previous objects, and it has different state than all of them. It's not alias to any of them, and it has no initial state until we get to something, I'll show you in a couple of minutes. When you assign one variable to another, like x=y that does create an alias and the reason why is this, y holds a reference to some object. And so when you say x=y they now both hold references to the same object, so they can both call methods on that object. And whatever private state of the object one method sets or changes will be seen by any other method on that object, and x and y both refer to the same object. In other words, they're aliased. So let's define a class to see all this in action. Again, we're just playing around with CLLI code here, I'll show you a real example, something that does something useful in a segment or two. So here's a class A, let's give it a m1 method that when you call it, assigns to the foo instance variable, the value 0. So what this will do is if the object already has an @foo, it will change it to 0. Otherwise, it will add one and initialize it to zero. m2 let's have it take some argument x and let's add to foo whatever was already there plus x and like in many programming languages, there's a little bit of syntactic sugar for this. We can write += x, and that does the same thing. And let's have a third method where the name of the method is foo and when you evaluate it, it evaluates the expression, look up the instance variable foo and return it because its the last thing in the method and methods return there last thing. And how about we just start with that simple class there and lets go over here I already have the IRB open. And let's load in the file there we are and now let’s just play around with those three methods in our one class A. So if I said something like x = A.new and then say y = A.new and said z = x based on our discussion of aliasing, x and y refer different objects, x and z refer to the same object. And we can see that been calling some methods. if I call x.foo, I'm going to get back nil. The reason why is when I call the foo method it reads @foo which has never been written to yet. So it's not part of the object state yet and so we get back nil. If on the other hand, I called x.m2 with 3 I actually get an error. The reason is here, I read @foo, which has never been assigned to on this object, get nil, and you can't call plus on nil. So that's why we got the actual error message, let's go ahead and fix that. If I call x.m1, that will, inside the object, set the instance variable foo to be 0, all right? And now remember that x and zero aliases so now if I call z.foo I actually get back zero not nil like I would had before. But if I call y.foo I still get nil because that object instance variable has never been assigned to. Okay, and we can do various things here, now we leave down this If we called z.m2 on 17, and then called x.m2 on 14, and then called z.foo, we would get 31. Of course, once I call x.m1, that's going to set foo back to 0 and so now, if I call z.foo, I get 0, so we really are updating state here. y is still over here with a nil, but if I called y.m1 and y.m2 7 and y.foo, I would get seven. So that's the idea of instance variables and now let's extend them a little bit. So first of all, of course, you could have more than one, maybe m2 would also make an @bar that would equal zero. But what I want to do now is tell you about a special method, method that has a special status in Ruby and that's a method called initialize. So it acts like any other method, but it is called when you create objects. So let's have this method initialized, taking one argument f and go ahead and initialize foo to be f. This is much better style so that we don't have to worry about m2 causing errors, or foo returning nil, we'll always have it initialized. In fact, you can make any method in Ruby taken a default argument so that if the caller doesn't pass an argument, it'll just default to 0. So how does this actually work? It turns out that you almost never call initialized directly, let me reload this so we can see this. It turns out, this is the warning that is referring to some file I haven't shown you yet. Some contents of the file I haven't shown you yet, it turns out in Ruby that when you say A.new. If your class has an initialized method, it will be called before the object returns. So now if I said something like q = A.new, it turns out that q already has a foo field that is initialized to zero. Similarly, if I call w with A.new, and I pass some argument like 19, whatever arguments you pass to new, get passed along to initialize. And since initialize can take one argument, we now have an object whose foo is 19 and after I call m2 on 7, I could ask w.foo and I get 26. So in general, it's just like any other method but new passes the arguments along and it gets called before new returns. Any methods has this issue where you can provide default values which allows the caller to call the method with two few arguments and the rest gets filled in as a default. So that's initialization, let me talk to you about that just a second here on the slide Initialize is special because of how it's called. It's excellent for creating objective variants. So what's going on here is its usually good style to create your instance variables in initialize but this is just a convention. In other programming languages, it's very common to have to say what your instance variables are. Sometimes, it's even required to initialize them in a method like initialize which in many programming languages is called a constructor but in Ruby, this is just a convention. And in fact, even different instances of the same class could, although it's not usually good style have different instance variables in their state. So that's the idea of instance variables to help contrast them with something else I want to show you a couple things about classes that I didn't show you before. So it turns out there are also things called class variables, and these are not separate for every object, they're shared by all the instances of a particular class. So different classes still have different class variables but all the objects of one class share the class variable. Syntactically we just use double @, so for example double @foo or @@foo is a class variable. These are frankly not particularly useful but you do some them every once in awhile. And I'm just showing them too here because they contrast the idea with you of private state for objects that instance variables are separate for every object and these are not. And as long as we're discussing classes, there's two other things that classes can have. The first is there are class constants, these are things justified in the class that start with a capital letter, you should not mutate them. I think in the current version of Ruby you get a warning, but don't ever mutate them. And these are just variables that can be used anywhere in the class, or outside of the class they are actually public, whereas class variables and instance variables are private. I'll talk about that more I think in the next segment. And outside of class C, if there were a class constant foo, you could write C::Foo to get it, and there's also a notion of a class method. Something that in Java is called a static method and the syntax for defining a class method, is you just write self. Before the rest of the method name, and I'm not going to explain here why. And then to use a class method, you don't write some object and then some method name in the argument. You write the name of the class, and then the method name in the arguments. You might guess that what's actually going on here is the class itself is also an object but let's not think of it that way right here. And class methods are just things that cannot access any instance variables of an instance of the class because they're separate from any object. They sort of explicitly say I'm not part of a particular object of class c. I'm just kind of a helper function that can use the class constants and class variables but not anything from a particular object of class C. So if we go back over here in the code, I have an example here of a class C that uses all these features. So here's a class variable Dans_Age, here is a class method that when you call it sets the class variable bar, you can see the double @ here to zero. And then, it's kind of like my previous example except now I have my m2 method increments the class variable bar in addition to what it used to do. And I've a new helper method here, bar that just returns the contents in the class variable. The one thing I wanted to show you is just as these class variables are really shared. So, if I make two instances of C and let me just go ahead and reset the bar class variable. Then if I say, c1.m1 of 7, sorry, m2, there's no m1 method and then c2.m2 9. And then I say c2.bar, it turns out I get back two which means that the bar field has been incremented twice. And that's because it's shared by the two objects, the objects are not aliased but they refer to the same class variable. On the other hand they have very different foo fields, C1 foo field is seven and C2 foo field is nine. And that's our introduction to instance variables, which are the state of objects as well as number of things that are shared by all instances of a class.