Skip to content

Latest commit

History

85 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Constructor

A collection of useful macros, mostly related to the construction of objects.

Installation

nimble install constructor

Constructor

constr works on procedures so you can match your preferred init method. You can pass other parameters to the object constructor by having a variable named the same in the main scope of the procedure. Aside from that it's practically like writting your own init procedure.

import constructor/constructor
typeUser=object
name: string
age: int
lastOnline: floatprocinitUser*(name: string, age: int): User {.constr.} # Can use like a forward declare.procinit(T: typedesc[User], name: string, age: int): User {.constr.} =result.lastOnline =30f
assertinitUser("hello", 10) ==User(name: "hello", lastOnline: 0f, age: 10)
assertUser.init("hello", 30) ==User(name: "hello", lastOnline: 30f, age: 30)

Defaults

You can use the defaults macro, which allows you to easily generate a constructor with default values. If your type is a value type the constructor is init<YOUR TYPE>() (e.g. initThingy()). If your type is a reference object the constructor is new<YOUR TYPE>() (e.g. newThingy()).

import constructor/defaults
typeThingy {.defaults: {}.} =object
a: float=10# Can do it this way
b ="Hmm"# Can also do it this way
c =10assertinitThingy() ==Thingy(a: 10, b: "Hmm", c: 10)

Flags

You can modify the generation of the defaults procedure by passing a set of DefaultFlag flags. Currently implemented flags are:

  • defExported - Adds a '*' to the proc so that it is exported (e.g. generates newThingy\*() instead of newThingy())
  • defTypeConstr - Changes the constructor signature for references from newThingy() to new(_: typedesc Thingy) and for value types from initThingy() to init(_: typedesc[Thingy])
  • defBothConstr - Includes both initThingy()/newThingy and new(_: typedesc[Thingy])/init(_: typedesc[Thingy])
import constructor/defaults
typeThingy {.defaults: {defExported, defTypeConstr}.} =refobjectofRootObj
a: float=10# Can do it this way
b ="Hmm"# Can also do it this way
c =10assertnew(Thingy)[] ==Thingy(a: 10, b: "Hmm", c: 10)[]
typeOtherThingy {.defaults: {defBothConstr}.} =object
d ="lula"assertinit(OtherThingy) ==OtherThingy(d: "lula")
assertinitOtherThingy() ==OtherThingy(d: "lula")

Struct Intialisers

A variant of positional initialisers exists inside constructor/structinits. There are type checks to ensure safety and it works on typedescs that are not object variants.

import constructor/structinits
typeMyType=object
x, y: int
z: stringMyRef=refMyTypeMyGen[T] =object
x: intassertMyType.init(10, 20, "hello") ==MyType(x: 10, y: 20, z: "hello")
assertMyType.new(10, 20, "hello")[] == (refMyType)(x: 10, y: 20, z: "hello")[]
assertMyRef.new(10, 20, "Hello")[] ==MyRef(x: 10, y: 20, z: "Hello")[]
assertMyGen[int].init(100) ==MyGen[int](x: 100)
assertMyGen[int].new(100)[] == (refMyGen[int])(x: 100)[]

About

Nim macros to aid in object construction including event programming, and constructors.

Resources

Stars

55 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages