Sapphire classes use attributes for state, methods for behavior, inheritance for specialization, and modules or abstract classes when you want stronger structure. Each runnable snippet uses the same WASM engine as the
playground.
Inheritance
Subclasses use < Parent. Call overridden methods with Ruby-style super to forward the same arguments.
shapes.spr
class Shape {
attr color = "red"
def area { 0 }
def describe {
"A #{self.color} shape"
}
}
class Rectangle < Shape {
attr width: Int
attr height: Int
def area {
self.width * self.height
}
def describe {
super + " (#{self.width}x#{self.height})"
}
}
r = Rectangle.new(width: 4, height: 5)
print r.describe # A red shape (4x5)
print r.area # 20
print r.is_a?(Shape) # true
Press Run to execute this snippet. ⌘↵ runs from the editor.
Private and class methods
Use defp for helpers that should only be called inside the class. A self { ... } block defines methods on the class itself, which is handy for factories.
account.spr
class BankAccount {
attr balance: Int = 0
self {
def open {
self.new(balance: 0)
}
}
def deposit(amount: Int) {
self.balance = self.balance + validate(amount)
}
defp validate(amount: Int) -> Int {
raise "amount must be positive" if amount <= 0
amount
}
}
account = BankAccount.open
account.deposit(100)
print account.balance
Press Run to execute this snippet. ⌘↵ runs from the editor.
Abstract classes
Use abstract class and abstract def when subclasses must share a base type and implement specific behavior before they can be instantiated.
abstract.spr
abstract class Shape {
abstract def area -> Float
def describe -> String {
"area=#{self.area}"
}
}
class Square < Shape {
attr side: Float
def area -> Float {
self.side * self.side
}
}
print Square.new(side: 4.0).describe
Press Run to execute this snippet. ⌘↵ runs from the editor.
Imports and local projects
The browser runner executes one file at a time, but local Sapphire programs can split code across files with relative imports: