[MUSIC] To begin our study of Ruby, we really need to understand and classes and objects because they are the center of the entire language. So, let's jump right in. There are just a few rules that will guide pretty much our entire understanding of the Ruby language. So let's go through those and then write some code that shows how they work. So in Ruby, all values, every result of the computation of the expression is going to be a reference to this we will call an object. And these objects communicate with each other and we use them by calling their methods. Methods are things like functions, but they belong to objects. As a synonym, we often sometimes say that we send an object a message. So sending it a message, or calling one of it's methods are really the same thing. We'll say that each object has it's own private state. I won't show that in this video, but we'll see it in just the next one. And then, each object has a class. That's the other thing we'll introduce in this segment, and what that class does, is determine the object's behavior. It's the class that defines the bodies, the methods that then belong to that object, so the class is going to contain those all important method definitions. You have seen another object oriented programming language some of this will be seem similar. Ruby is just more extreme about it in that every object only has private state, and all that we have in our language are objects. So what we need to do first is learn how to define classes because then we'll use the classes to make the objects. And you see here the basic syntax and I'll show you an example here in just a second. You say keyword class, the name of your class which has to be capitalized, actually. Then an equals, then one or more method definitions which all looked like def, the name of the method and so on. I'll show you an example. And then that can be your class definition. We'll have some additions to class definitions as we go through the language but this will get us started. So let's just go over here and do it a little bit. I've got a blank file with just some comments in it so far and let's just define a class A. I don't think I need the equals actually which I had on the slide, I'll fix that later. And let's define a method. This is a method m1, that objects that have class A will have and when you call this method you always get back 34. So that's all there is to it. Let's define a second method. Let's have this one take in two arguments, x and y. I'm in a dynamically typed language. So I can pass in any objects at all. And then let's have the body of my method. First have some local variable z that will hold 7. Then how about a conditional? How about if x > y then false. Else x + y * z end. So this, that if else end, that's my conditional statement. It turns out that these new lines are actually important you need that then branch on its own line. If you want to put it on the same line you need more syntax, you need the keyword then. And you can look up in the Ruby documentation, the 50 different ways to write a conditional expression and I'm only exaggerating slightly. And then a second end that will end the method definition, right? And then if that's all I wanted in my class, I could then end the class. And if that were my file, it turns out I can then go over to IRB which I already have opened here and I could load the file that I just made. And that would work fine. And then I could make objects whose behavior is defined by that class. The way you do that is you write the name of the class.new and that would make an object. And since I want to use this object later, how about I assign it to a variable. So A = A.new. And now what I can do is I can call that object's method. So A refers to an object. So if I wanted to call the m1 method, I take the object, write dot then m1. And I get back 34. because if you remember here from the code, the m1 method returns 34. If I call the m2 method, I get an error if I don't pass the right number of arguments. It really is a two argument method. So, I can pass arguments in parentheses with commas in between them. So if I pass, for example, a.m2 with 3 and 4, I'll get back 31. And that's because over here in the code, if you follow the arithmetic, if x is 3 and y is 4, I end up taking the else branch. And 3 + 4 x 7 = 31. So that's just one class, I can make as many objects of that class that I wanted. But instead how about make a new class to show a couple of different things. So how about I make a class B and it can have an m1 method that takes no arguments and returns 4. How about it also has an m3 method that takes one argument x, so you can put parenthesis around it if you want to, it's optional. And what it does is it takes that x object, sends it the message abs. So it calls it's abs method, multiplies that by two and then adds what I'll call self.m1. And there and there. So what is self? Self is special word, kind of like a variable, kind of like a key word. And what it says is, this object, myself. So whenever I execute this code it'll be because I called some method on some object. And what self always means is, the object I called the method on. So in this case, if I say self.m1, that means called this method, with the same object, on the same object. So it'll be sending your self a message in particular this message which will then return a 4. So if I had this, I could go over here. Let's real quick quit the rb and start over, and load classes_objects.rb. Okay, and now what I could do, is I could make, you know I could continue just like I did before. Of saying, a is A.new and then m.m1, but I could also make a variable that holds a B object. Did I forget to save this here? I did. Okay. Let's just reload it. All right. And now it should work. Good. And now I could say b.m1 and I would get 4 because it's M1 method, always returns 4, or I could try b.m2. Here, it's an undefined method even if I pass with two arguments. Objects that have class B do not have an M2 method. If you remember back here with the code, instances of class B have an M1 method and M3 method. So similarly, I could not say a = A.new and then a.m3. That would not work. But I could say b.m3. It takes one argument, how about 5? And it ends up returning 14, why is that? Because if you send 5 the abs message, you end up getting back 5. It turns out this is the absolute value method. If you call numbers with abs, so if I say 5.abs. I get back 5. And if I say -5.abs. I would also get 5. Multiply by 2, you get 10. Then call self.m1 and you get 4 back. So that's most of what I wanted to show you in terms of code. I'll show you one more thing here in a second. But just to review what we've done so far, once we've defined a class, then you can say className.new to create a new object whose class is that class name. Whenever you write e.m, e is an expression, m is some method name. What that does is evaluate e to an object, and then call that objects m method. You can also, if you're calling a method with zero arguments right, left parentheses, right parentheses, if you want, it's optional. It's a matter of personal taste and style. Methods that take arguments, you separate by commas. These parentheses are occasionally optional but you usually need them and I recommend you just always put them in. If you have even more than one argument and even one, it's probably wise. In terms of variables we did see a few variables here. Methods can use local variables they just start with a letter and you just put them anywhere you want in the method body and their scope is the entire body. So this is a strange thing we haven't seen in languages we've studied before. You don't declare your variables, you don't have any kind of let expression. You just assign to them anywhere and they spring into existence for the entire method body. Variables are mutable, I didn't show you that, but I could have. For example over here where I had these local variable z in this method m2 anywhere I want it in the method. Set it, maybe made it +=3, that would turn z into 10, for example. Variables are also allowed in the REPL or outside of a class at top-level for when you're testing your program or playing around with things. And a variable will always have as its contents a reference to some object. If you update a variable, then it will refer to some different object. But it always refers to an object. And finally, we have the special thing called self. Self is a special word. It refers to the current object whose method is currently executing. And so when we wanted one method to call another method in the same object, we wrote self.m. Now the truth of the matter is, I was showing that to you so that we understood the idea. You do not have to write self dot, if you call a method without anything to the left and no dot, it's implicitly self. That's the default. So the syntactic sugar is you can leave off the self dot. The one other thing I wanted to show you is that you can use self by itself, pardon the expression there. When you just write self rather than calling a method of self, you really do mean the whole object that is currently executed and that can be a useful thing. So let me show you a quick example here. I have another class down here, already defined C that has three methods m1, m2 and m3. M1 and m2 just print a string "hi" or "bye" and this print command doesn't put a new line afterwards, and then m3 just prints out a new line, so you move to the next line. But instead of just ending with the print statement, they then as their next expression on the next line, return self. And what that does is kind of weird. It has these methods return themselves as objects. And as a result, it lets us string methods together in kind of a convenient way. So let me show you that here in the code. Let me just make a new C object. Okay, so now what I could do is I could call c.m1, and that would print hi. But because it gives the object back, I could take the result and call m2 and then it would print hi bye. And I could string these together as long as I want. How about .m3.m3.m1.m1.m3, okay. And then it printed hi bye, a blank line and hi and hi. This is not a particular language feature. All that's going on is since c.m1 returned an object, I can then call its m2 method. It just so happens that what c.m1 returned is the same object as c is. So I could string together these multiple calls in this way and this is a fairly common idiom that you see in Ruby. The last thing I will mention about the code before we end this segment. Is that I didn't right any semicolons here between my expressions. You can do so, you are welcome to do so. But in Ruby, often new lines, putting things on separate lines, have significance. Because these are on separate lines I don't need a semicolon. But if they were on the same line, then I would. So in Ruby, it often matters where you put new line characters and that can take a little getting used to. Just to assure you of any concerns, indentation never effects semantics in Ruby. It does in some languages, but indentation like in the other languages we've studied is just a matter of style. So we've seen a lot of new things here but the two important things we saw were classes for defining methods and the new operation for creating objects of certain classes and then we could call those methods.