GGistDev

Classes and Objects in Ruby

Everything is an object; classes define blueprints and behavior.

Defining a class

Initialize state in initialize; attr_reader/attr_accessor define accessors.

class User
  attr_reader :name

  def initialize(name)
    @name = name
  end

  def greet
    "Hi, #{@name}!"
  end
end

u = User.new("Ava")
u.greet   # => "Hi, Ava!"

Attribute helpers and custom writers

Use attr_reader, attr_writer, attr_accessor; write custom setters to validate.

class Temperature
  attr_reader :celsius
  def celsius=(value)
    raise ArgumentError unless value.is_a?(Numeric)
    @celsius = value
  end
end

Class methods and class instance variables

Define methods on the class itself with self. or class << self; prefer class instance variables over class variables.

class User
  @count = 0
  class << self
    attr_accessor :count
    def from_json(json)
      data = JSON.parse(json)
      new(data["name"])
    end
  end
end

Inheritance and super

Subclass behavior and extend/override methods; call super to reuse parent logic.

class Admin < User
  def greet
    "[ADMIN] " + super
  end
end

Method lookup order

Inspect with ancestors; includes prepended/included modules before superclasses.

User.ancestors

Equality and identity

== is value equality, eql? stricter for Hash keys, equal? is object identity.

"a" == "a"      # => true
"a".eql?("a")  # => true for strings; may differ for other classes
obj1.equal?(obj2) # same object?

String representation and freezing

Override to_s (human) and inspect (debug). Freeze to make objects immutable.

class User
  def to_s
    "User(#{@name})"
  end
  def inspect
    "#<User name=#{@name.inspect}>"
  end
end

u.freeze
# u.name = "x" would fail only if you write custom mutators; freezing prevents future modifications to the object state

Summary

  • Use initialize for setup; attr_* for accessors and custom writers for validation
  • Define class methods via self. / class << self; prefer class instance variables
  • Understand lookup with ancestors, and use ==/eql?/equal? appropriately