पाठ 7 / 25
Classes, Attributes and Initialisation
Define classes with initialize, attribute accessors and useful conversion methods.
Defining your own objects
Define a class with class Invoice ... end. initialize runs when you call Invoice.new(...) and usually sets instance variables (@number), which are private to the object. Expose them with attr_reader (getter), attr_writer (setter) or attr_accessor (both); prefer readers and explicit methods over writers, so objects stay valid. Methods return their last expression. Define to_s for a human-readable string and rely on inspect for debugging output. Class methods are defined with def self.from_csv(row), useful for alternative constructors. Inside a method, self is the current object. Methods ending in ? return booleans by convention (paid?), and methods ending in ! are "dangerous" variants (mutating or raising). Equality is customisable by defining ==, eql? and hash, and <=> plus include Comparable gives you <, >, between? and clamp. Since Ruby 3.0, short methods can use endless method syntax: def total = items.sum(&:price).
An object's state and behaviour
Instance variables hold private state; public methods expose behaviour and selected data.
An invoice class
Readers, predicates, a class-level constructor and an endless method.
class Invoice
attr_reader :number, :items
def initialize(number, items = [])
@number = number
@items = items
@paid_at = nil
end
def self.from_hash(data) # alternative constructor
new(data.fetch(:number), data.fetch(:items, []))
end
def total = items.sum { |i| i[:price] * i[:qty] } # endless method (Ruby 3.0+)
def paid? = !@paid_at.nil?
def mark_paid!(at = Time.now)
raise "Invoice #{number} already paid" if paid?
@paid_at = at
self
end
def to_s = "Invoice #{number}: Rs #{format('%.2f', total)}"
end
inv = Invoice.from_hash(number: "INV-7", items: [{ price: 49.5, qty: 2 }, { price: 1200, qty: 1 }])
puts inv # Invoice INV-7: Rs 1299.00
inv.mark_paid!
puts inv.paid? # trueAvoid attr_accessor by default
attr_accessor lets any code set any value, bypassing your rules. Start with attr_reader, and add methods such as mark_paid! that change state while checking invariants.
त्वरित जाँच: What does attr_reader :number create?
- A getter method number that returns @number
- A setter only
- A class variable
- A constant
Answer
A getter method number that returns @number — attr_reader defines a reader method for the instance variable.