[music] In this segment, I want to talk a little bit more about which parts of a Ruby program can access and use which other parts of a program since that's an essential aspect of any programming language. As we know, hiding things is essential for modularity and abstraction. That's why we studied, for example, the module system in ML. And object-oriented programming languages generally have various ways to take what Ruby calls instance variables, methods, classes, etc. And make them available to only part of a program. So we can use Ruby as a good example of the sort of decisions that languages tend to. To make. So, Ruby does one thing that I actually like quite a lot, which the, it emphasizes that object state is always private. So, instance variables can only ever be accessed by methods on the actual object that has that instance variable. Not even another object of the same class. So as a result when we access or assign to an instance variable we always write @foo. We never write e.@foo, because you're not allowed to access @foo for any object other than self. And so self dot would be redundant, and you're not even allowed to write it. So, to make objects stay publicly visible, when that is what we want, when we want the outside world to know the content, to be able to update the contents of an instance variable, then we need to define our own methods to do that. And we can do that explicitly and these methods are usually called getter methods when they return the contents of a field and setter methods when they update the contents of the field. So in Ruby we could very easily return the contents of the foo instance variable with a method like get_foo whose expression just looks up the contents and returns it. And similarly set_foo could take some argument x and assign to the instance variable because the method is allowed to access at foo and in this way we can provide access via the set foo method. Now that said, this is common enough in Ruby that there's some built in support for it and further more, the conventional names are slightly different than I showed on the previous slide. The convention in Ruby is that if you want a getter method for the instance variable @foo, just call the method foo. And if you want a setter method call it foo equals. It turns out in Ruby your allowed to have a method end with the equals character, and that's the convention for a setter method. This convention actually goes one step further. There's a cute piece of syntactic surgar in Ruby, which is if you do have a method that ends in equals, when you write a call to that method your allowed to have. White space, space characters between the non equals character and the equal. So, it turns out in Ruby, you can write e.foo space equals some expression. And that's the exact same thing as foo without the space. It is literally a method call to the foo, foo equals method. Nothing more, it just makes using setters look nicer. Furthermore people felt that writing getters and setters like this was three lines long and that was just too long. So there are other ways you can accomplish the same thing in ruby. If you want getter methods foo and bar for instance variables at foo and at bar. You can just write attr underscore reader, it's short for attribute reader, colon, foo, comma separated, and then the names of all the methods preceded with colons that you want getter methods for. And, I'm not going to explain what the colons mean, and why this is the exact syntax, but you're welcome to use this shorter form. Form. And if you want getters and setters, you just say attr underscore accessor, and if you said colon foo that would define both the method foo, and the method foo equal. But these are just shorthand versions. All we are doing are defining getter and setter methods for accessing the instance variables in a way that makes them truly private to the object. And it's only the methods that are giving the outside world an Indirect way to access them. So why private object state? Well it turns out most people would agree that requiring these instance variables to be private to just the object makes the object more in an object oriented programming style. That it let's you focus on the interface to an object what method you can call. Without knowing how the object is actually represented. Why is that good? It's for all of our normal abstraction and modularity reasons. That way later the class implementation could change and clients are not messed up by there being different instance variables or different implementation of the same methods. In fact it hides from clients how the actual instance variables are storing the data. I have acute example here on the slide where maybe I give clients a method celsius_temp= which they would probably assume was a setter method for an instance variable, celsius temp. But maybe internally the class finds it much easier to store temperatures in kelvin, and it simply implements this setter method by writing to a kelvin temperature instance variable inappropriately shifted value. In fact you can do this for different classes, that represent internal state in entirely different ways and this is related to the idea of duck typing, that we'll talk about in a slightly future segment. So that's the story for instance variables. Now let's talk about methods. So it turns out Ruby has three different visibilities, three different rules that it can apply to methods and you can choose for each method which one you want. So you can have private methods which, just like private instance variables, can only be used by other methods of the same object. You could have protected which cannot be used by just anyone. A protected method can only be used by objects of the same class or any subclasses. And we still have to discuss subclasses. So it doesn't have to be the object itself, but it does have to be the same class or a sub-class. And then there's public, and a public method can be called by anyone who has access to the object. If you have the object, it has a public method m, you can call m on it. So, the default for methods is public, and that makes some sense. The entire purpose of an object is to call methods on it, but there are various ways, there are always various ways in Ruby, various ways to change the visibility of an object. Let me just show you one way. Here on this next slide. So when your define some class foo, and you're going to have a bunch of method definitions, the default as I mentioned, is public. So when you start defining methods, all those methods will be public. But in your class definition, you can use the keyword protected and once you write that word in between methods, then all the following methods will have the protected visibility instead of public. And similarly, you could then switch back to public, so it's a keyword as well. And then that would make these the method definitions after this public be public, and there's a keyword private. So basically what you do is when you have a method definition, to figure out its visibility, you find the most recent use of protected public or private, and that's what it is. Uh,and at the beginning of the class it's like there's an, an implicit public to get things started. So that's really the entire story on method visibility to the extent I want to get into it. There is one detail which is for private methods, it turns out since the only methods that are going to able to call that method are methods on the same object, you can always just write m or m of args. Because as we know that shorthand for self.m, that's a short way of writing a method call on the same object. But for private methods, that's the only call that is allowed and so Ruby actually forces you to use the shorthand. Any other object here would not be allowed by under visibility rules. You would think it would allow self dot, just because you wanted to remind yourself that it was a call on the same object. But, in fact, it really does not allow it even syntactically. You cannot write the self dot on a private method. You just have to call the method with the short form that does not indicate which object you're calling the method on. And that's everything we need to know about method visibility in Ruby.