Skip to content

ddn.var

A compact, dynamic value type for the D programming language.

Overview

The ddn.var module provides a versatile dynamic value type (var) that can hold values of many different types at runtime. It is designed to be compact, efficient, and easy to use for scenarios where static typing is impractical—such as configuration handling, JSON-like data structures, or scripting interfaces.

Features

Supported Types

The var type supports a comprehensive set of value types:

Type Category Supported Types
Null NULL — absence of a value
Boolean BOOLtrue or false
Integers BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG
Floating Point FLOAT, DOUBLE, REAL (stored as double internally)
Characters CHAR, WCHAR, DCHAR
Strings STRING — UTF-8 encoded strings
Collections ARRAY — dynamic array of var, OBJECT — associative array (stringvar)

Type Conversion

Use the as!T template to convert a var to a specific D type:

import ddn.var;

var v = 42;
int i = v.as!int;      // Extract as int
string s = v.as!string; // Convert to string representation

var arr = [1, 2, 3];
var[] elements = arr.as!(var[]); // Extract array elements

Object/Map Access

Access object fields using indexing or the convenient opDispatch syntax:

var obj;
obj["name"] = "Alice";
obj["age"] = 30;

// Read values
string name = obj["name"].as!string;
int age = obj["age"].as!int;

// opDispatch syntax (field-like access)
obj.email = "alice@example.com";
string email = obj.email.as!string;

Array Operations

Work with dynamic arrays naturally:

var arr = [1, 2, 3, 4, 5];

// Access by index
var first = arr[0];

// Get length
size_t len = arr.length;

// Iterate
foreach (ref el; arr.as!(var[])) {
    // process element
}

Arithmetic Operations

Perform arithmetic on numeric var values:

var a = 10;
var b = 3;

var sum = a + b;      // 13
var diff = a - b;     // 7
var prod = a * b;     // 30
var quot = a / b;     // 3 (integer division)
var rem = a % b;      // 1

// Division/modulo by zero returns NULL (not an error)
var zero = 0;
var result = a / zero; // result.type == Type.NULL

Deep Copy with dup() and idup()

Assignment of var values is shallow for arrays and objects. Use dup() for deep copies:

var original;
original["nested"] = [1, 2, 3];

// Shallow copy (aliases the nested array)
var shallow = original;
shallow["nested"][0] = 99;
assert(original["nested"][0].as!int == 99); // Both changed!

// Deep copy (independent)
var deep = original.dup;
deep["nested"][0] = 42;
assert(original["nested"][0].as!int == 99); // Original unchanged

JSON Serialization

Convert var values to JSON strings:

var data;
data["name"] = "example";
data["values"] = [1, 2, 3];

string json = data.toJSON();
// Output: {"name":"example","values":[1,2,3]}

Error Handling

The ddn.var module follows a non-throwing error handling strategy:

  • Debug assertions catch programmer errors (e.g., indexing a non-map) during development.
  • Recoverable operations return status values or defaults instead of throwing:
    • remove(), insert(), removeAt() return bool success indicators.
    • as!T returns T.init for incompatible conversions.
    • get(key, default) returns the default if the key is missing.
    • Division/modulo by zero returns var.init (NULL).

Thread Safety

  • var does not perform internal synchronization.
  • Concurrent mutation of the same instance is a data race.
  • Independent copies can be used in different threads.
  • For shared access, use external synchronization (e.g., Mutex) or message passing.

See Also