Wow. So there were alot of topics that were covered today so I'll try to go slowly with some very basic examples, but please forgive me if my post seems a bit jumbled. To be clear, self is a topic unto it'self'(haha, get it?) but I'm including it here because I think it's a great way to also think about scoping in context of Class.
So what is self? The quick and dirty definition is a keyword that gives you access to w/e self is encapsulated in. A more accurate definition is the object that's receiving the method. In any case, self is important because depending on where it's located, you could be referencing different objects. Let's take a look at some examples.
In this context, self is encapsulated within an instance variable of class Cat. If we were to call .meow as on line 7, we would receive an id of an instance of the class Cat.
However, if we were to look at this image, self is part of the method. If we were to try and call the method as on line 15, we would get an error. Now think about that for a bit.
The reason why we get an error on Dog but not Cat has to deal with the scope of our Dog or Cat. Since our self is found within a instance method meow, we are allowed to call meow as on line 7 in the first example with no problems. On the other hand, by putting self on the method for Dog, we change the method to a class method. Therefore we get an error on line 15 because in writing Dog.new, we are creating an instanceof the Dog class.