Repository navigation
Documentation
import oolib
# create Person type
class Person:
var
name*: string
age* = 0
let
tony = Person.new("Tony")
steve = Person.new("Steve", 100)
doAssert tony.name == "Tony"
doAssert tony.age == 0
doAssert steve.name == "Steve"
doAssert steve.age == 100pub is instead of *.
example:
# `A` is exported
class pub A
# `B` is not exported
class Bclass can define member variables starting with var and they can be set to default values.
class A:
var a: int
var b: string
class B:
# infer types from default values
var
c = "default"
d = 1.5Data constants are constants that can be accessed from both a type and an instance.
they start with const and their value must be set when a class is defined.
class MoneySymbol:
const JPY = "¥"
const US = "$"class defines constructor automatically from definition of member variables in its body. Once a class is exported, a constructor is also exported.
example:
class Sword:
var offence: int
proc attack() =
echo "attack!"
# `Sword.new` is automatically defined.
let sword = Sword.new(9)When a variable has a default value, an argument of constructor has a default value just like it.
class List:
items: seq[string] = @[]
var
list1 = List.new(@["apple", "orange"])
list2 = List.new()class auto-inserts followings:
- return type
- member variables with default values as arguments of constructor
-
var self: Typein the 1st line of constructor -
return selfin the last line of constructor
class Gun:
var
capacity: uint
bullets: uint
proc `new`(capacity: uint) =
self.capacity = capacity
self.bullets = capacity
proc shoot() =
if self.bullets > 0:
self.bullets = self.bullets - 1
else:
echo "Out of bullets!"
let gun = Gun.new(6)Mark with {.noNewDef.} not to define constructor.
class Data {.noNewDef.}:
var x, y: int
discard Data.new(1, 2) # error!class supports proc, func, method, iterator, converter, and template, with the only exception being macro.
For these, self is automatically inserted as the first argument.
class can omit its body.
class A:
discard
# is same as
class BGeneric types are supported only in normal classes for now and cannot be used in member variables.
class A[T]:
proc f1[T](s: seq[T]) =
for i in s:
echo i
let a1 = A[int].new()
let a2 = A[string].new()
a1.f1 @[4, 2, 4]
a2.f1 @["a", "b"]Inheritance is done as follows:
# Mark {.open.} to be inheritable
class A {.open.}
class B of A
# This will be parsed as Alias
class B(A)
# This is not inheritable
class C
# error!
class D of CSuperclass must be marked with {.open.}.
In methods of class, super keyword is defined to access superclass.
from typetraits import name
class A {.open.}:
method abstractMethod {.base.} =
echo &"Abstract method of {self.type.name}!!!"
class B of A:
method concreteMethod =
super.abstractMethod()
echo &"Concrete method of {self.type.name}!!!"example:
class Dollar(distinct int):
proc `+`(v: Dollar): Dollar {.borrow.}
proc `$`: string {.borrow.}
echo 100.Dollar + 50.Dollarexample:
# It's same as `type A = int`
class A(int)class can implement protocol, described later.
It returns whether a type is class or not. example:
class A
let a = A()
# Both are available
assert A.isClass()
assert a.isClass()protocol provides tuple for interface. For now, multiple implementation is not supported.
protocol Animal:
var scientificName: string
proc breathe()
proc roar()
class Cat impl Animal:
var scientificName: string
var name {.ignored.}: string
proc breathe() =
echo "breathed!"
proc roar() =
echo "meow!"
class Dog impl Animal:
var scientificName: string
var name {.ignored.}: string
proc breathe() =
echo "breathed!"
proc roar() =
echo "bark!"
let cat = Cat.new("Felis catus", "Leo").toInterface()
let dog = Dog.new("Canis lupus familiaris", "Wolf").toInterface()
cat.breathe()
cat.roar()
dog.breathe()
dog.roar()pub is instead of *.
protocol can define member variables starting with var and they cannot be set to default values.
protocol can force class to implement procedures.
protocol Walkable:
proc walk()
class Person impl Walkable:
proc walk() = echo "Walking!"
# error!
class Robot impl Walkable:
proc run() = echo "Running!"Mark with {.ignored.} to ignore properties that isn't defined in protocol.
protocol SNS:
var username: string
class Discard impl SNS:
var username: string
var mail {.ignored.}: string
var password {.ignored.}: string
proc verify() {.ignored.} =
discarda class that implements a protocol has toInterface() to be converted to interface.
protocol Weapon:
var offence: int
class Sword impl Weapon:
var offence: int
class Hatchet impl Weapon:
var offence: int
class Player:
var equipment: Weapon
let sword = Sword.new(5).toInterface()
let hatchet = Hatchet.new(4).toInterface()
let player1 = Player.new(sword)
let player2 = Player.new(hatchet)It returns whether a type is protocol or not. example:
protocol A:
var val1: int
let a: A = (val1: 1)
# Both are available
assert A.isProtocol()
assert a.isProtocol()