Skip to main content

Data Library (Data)

Every field and function is backed by a Data handle — this library is how you work with that handle directly, rather than through the field or function it's attached to. Advanced, low-level territory; most code never needs this.

Locating Data

Data.field(path: str) -> data

A data pointer to a field, by path from the current object.

data-field.stof
myfield: 42

#[main]
fn main() {
  const ptr = Data.field('self.myfield');
  pln(ptr.exists());
}
Output

Data.id(ptr: data) -> str

data-id.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const id = func.data().id();
  pln(id.len() > 0);
}
Output

Data.from_id(id: str) -> data

The other direction — reconstruct a pointer from an ID string.

data-from-id.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const id = func.data().id();
  pln(Data.from_id(id) == func.data());
}
Output

Data.libname(ptr: data) -> str

Which library this data is linked to, if any.

data-libname.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  pln(func.data().libname());
}
Output

Data.objs(ptr: data) -> list

Every object this data is attached to.

data-objs.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  pln(func.data().objs().front() == self);
}
Output

Attaching, Moving & Dropping

Data.attach(ptr: data, obj: obj) -> bool

Makes this data reachable from an additional object, under the same name.

data-attach.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const other = new {};
  func.data().attach(other);
  pln(other.hi());
}
Output

Data.move(ptr: data, from: obj, to: obj) -> bool

A drop and an attach in one step — removes the data from one object and places it on another.

data-move.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const other = new {};
  func.data().move(self, other);
  pln(other.hi(), self.hi);
}
Output

Data.drop(ptr: data) -> bool

data-drop.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  pln(func.data().drop());
}
Output

Data.drop_from(ptr: data, obj: obj) -> bool

Drops from one specific object — if that was the only object referencing it, the data leaves the document entirely.

data-drop-from.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  pln(func.data().drop_from(self));
}
Output

Serialization

Data.blob(ptr: data) -> blob

Serializes the data (name, attributes, value — everything) into bytes.

data-blob.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const bin = func.data().blob();
  pln(bin.len() > 0);
}
Output

Data.load_blob(bytes: blob, context: obj | str = self) -> data

The other direction — deserializes into a specific object, effectively copying the data onto it.

data-load-blob.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const bin = func.data().blob();

  const other = new {};
  Data.load_blob(bin, other);
  pln(other.hi());
}
Output

Validity

Data.exists(ptr: data) -> bool

False once the data has been dropped — a pointer held onto after that point doesn't resurrect it.

data-exists.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func: fn = self.hi;
  const ptr = func.data();
  drop(func);
  pln(ptr.exists());
}
Output

Data.invalidate(data: data, symbol: str = 'value') -> bool

Marks data as invalid under a symbol — a lightweight dirty-flag mechanism, throws if the data doesn't exist.

data-invalidate.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func = self.hi;
  const ptr = func.data();
  pln(ptr.invalidate('something_happened'));
}
Output

Data.validate(data: data, symbol?: str) -> bool

Clears an invalidation — returns true only if it was actually invalid under that symbol (or any symbol, if none given) beforehand.

data-validate.stof
fn hi() -> str { 'hi' }

#[main]
fn main() {
  const func = self.hi;
  const ptr = func.data();
  ptr.invalidate('something_happened');

  pln(ptr.validate('something_happened'));
  pln(ptr.validate('something_happened'));
}
Output