पाठ 9 / 25

Inheritance, Visibility, Struct and Data

Use inheritance and method visibility, and create value objects with Struct and Data.

Inheritance and lightweight objects

A class inherits from one superclass with class SavingsAccount < Account; it can override methods and call the parent's version with super (bare super forwards the same arguments, super() passes none). Every class ultimately inherits from Object (and BasicObject). Method visibility controls access: methods are public by default; private methods can only be called without an explicit receiver (on the current object); protected methods can be called by other instances of the same class family, useful for comparisons. For simple data holders, Struct.new(:sku, :price) generates a class with accessors, equality and to_a, and Data.define(:sku, :price) (Ruby 3.2) creates immutable value objects with keyword or positional construction, equality by value and with for modified copies. Prefer composition and modules to deep inheritance trees, and use Data for values such as money, coordinates and API results that should not change after creation.

Inheritance, private methods and Data value objects

super, visibility and an immutable value object.

class Account
  attr_reader :owner, :balance

  def initialize(owner, balance = 0)
    @owner = owner
    @balance = balance
  end

  def deposit(amount)
    validate!(amount)
    @balance += amount
  end

  private

  def validate!(amount)
    raise ArgumentError, "amount must be positive" unless amount.positive?
  end
end

class SavingsAccount < Account
  def initialize(owner, balance = 0, rate:)
    super(owner, balance)                           # explicit arguments to the parent
    @rate = rate
  end

  def add_monthly_interest = deposit((balance * @rate / 12).round(2))
end

Point = Data.define(:lat, :lng) do
  def to_s = "(#{lat}, #{lng})"
end

pune = Point.new(lat: 18.52, lng: 73.86)
moved = pune.with(lng: 73.90)                       # a new object; pune is unchanged
puts pune == Point.new(lat: 18.52, lng: 73.86)       # true: value equality
# pune.instance_variable_set(:@lat, 0)              # FrozenError: Data objects are frozen

Data for values, classes for behaviour

If an object is mainly a bundle of values that should not change (an address, a money amount, a coordinate), Data.define gives you immutability and value equality for free.

त्वरित जाँच: What does Data.define (Ruby 3.2+) create?

  • A database table
  • A mutable struct with setters
  • An immutable value-object class with value equality
  • A module
Answer

An immutable value-object class with value equality — Data classes are frozen value objects with keyword construction and equality by value.