Ruby is fundamentally object-oriented, and classes are defined with the class keyword followed by the class name and a body of method definitions. When an object is created with ClassName.new, the special initialize method is automatically called as the constructor, allowing the new instance to set up its own state. State is stored in instance variables prefixed with a single at sign, such as @name, which live for the lifetime of the object and are accessible from any instance method.
Class variables, prefixed with two at signs like @@count, are shared across all instances of a class and any subclasses that inherit from it. Because subclass changes affect the same variable, they should be used with caution. Ruby supports single inheritance through the less-than symbol: writing class Dog < Animal declares that Dog inherits the behavior of Animal, and any class implicitly inherits from Object unless it specifies another parent.
Modules are Ruby's answer to the lack of multiple inheritance. A module is a container for methods and constants that cannot be instantiated directly. It serves two roles: as a namespace that groups related classes together, and as a mixin that adds behavior to a class through include or extend. Including a module makes its methods available as instance methods of the class, while extending a module adds those methods as class methods. To eliminate boilerplate getter and setter definitions, Ruby offers the attr_reader, attr_writer, and attr_accessor class macros, which generate the corresponding methods for the named symbols. The Comparable module is another built-in mixin: by defining the spaceship operator and including Comparable, a class gains all the standard comparison operators for free.