zuri.reflect
import zuri
zuriexposes this aszuri.reflect, soimport zuriis enough and the names are called aszuri.reflect.*.import zuri.reflectreaches the same definitions directly.
Runtime introspection: metadata about a live function, class, or module, and property/method access on an instance or module by name, without needing to already know that name at compile time. It also runs the garbage collector on demand.
This is deliberately a RUNTIME-only view. It does not know a
function/class’s declaration line or its doc block; those live in
source, not in the running object, and are a zuri.parse()/zuri AST
concern instead (walk the parsed source and read a Function/Class
node’s own line/col, and any DocBlock node sitting right before
it).
import zuri
def add(a, b) {
return a + b
}
echo zuri.reflect.function_info(add).arity
# 2
Functions
kind()
zuri.reflect.kind(value) -> string
This value’s runtime type tag: 'nil', 'bool', 'number',
'string', 'bytes', 'bigint', 'list', 'dict', 'function',
'class', 'instance', 'module', 'range', 'file', or a pointer’s
own registered resource tag (see pointer_type). A closure, a native
function, and a bound method are all reported as 'function', since
from Zuri’s own point of view they’re interchangeably callable.
Parameters
value(any)
Returns string
pointer_type()
zuri.reflect.pointer_type(value) -> ?string
The registered resource tag a pointer value was allocated with (e.g. a
native socket handle’s own internal type name), or nil if value
isn’t a pointer at all. Pointers wrap an opaque native resource that
Zuri code can’t otherwise inspect; this names what kind of resource one
is without exposing its contents.
Parameters
value(any)
Returns ?string
function_info()
zuri.reflect.function_info(f) -> dict
Metadata for a function-like value: { name, arity, variadic, is_method, owning_class_name, source_path }.
owning_class_name is the class it was declared a method of, or nil
for an ordinary function/closure. source_path is nil for a native
(built-in) function, which has no Zuri source file behind it.
Parameters
f(callable) — A closure, a native function, or a bound method
Returns dict
Raises Error if f isn’t callable as a function (a class, though
itself callable to construct an instance, is a class_info subject
instead)
class_info()
zuri.reflect.class_info(c) -> dict
Metadata for a class: { name, superclass_name, methods, fields, statics }.
superclass_name is nil for a class with no superclass. methods is
a dict from method name to that method’s own function_info-shaped
entry, own and inherited pre-merged (an override shadows the inherited
entry of the same name, matching how method dispatch itself works).
fields and statics are plain lists of names, ordered by declaration;
fields includes inherited fields, statics is own-only (statics are
never inherited in this runtime).
Parameters
c(class)
Returns dict
Raises Error if c isn’t a class
module_info()
zuri.reflect.module_info(m) -> dict
Metadata for a module: { name, path, loaded, members }. members is a
dict from every top-level name the module declares to that binding’s own
kind (see kind above), e.g. { add: 'function', VERSION: 'string' }.
Accepts either a raw module value or a promoted import PATH binding;
both describe the same underlying module.
Parameters
m(module)
Returns dict
Raises Error if m isn’t a module
info()
zuri.reflect.info(value) -> dict
Dispatches to function_info/class_info/module_info based on
kind(value).
Parameters
value(any)
Returns dict
Raises Error if value has no reflectable shape (a number, a
list, an instance, …); reflect describes callables, classes, and
modules only
has_prop()
zuri.reflect.has_prop(object, name) -> bool
Does object (an instance or a module) have a property/member named
name?
Parameters
object(instance|module)name(string)
Returns bool
get_prop()
zuri.reflect.get_prop(object, name) -> any
The current value of object’s (an instance or a module)
property/member named name, or nil if it has none by that name.
Parameters
object(instance|module)name(string)
Returns any
Raises TypeError if object is neither an instance nor a module
get_props()
zuri.reflect.get_props(object) -> list[string]
Every property/member name object (an instance or a module) has, as a
list of strings, or an empty list if it has none. Instance fields are
ordered by declaration; module members have no such inherent order.
Parameters
object(instance|module)
Returns list[string]
Raises TypeError if object is neither an instance nor a module
set_prop()
zuri.reflect.set_prop(object, name, value)
Overwrites object’s existing property name with value.
Parameters
object(instance)name(string)
Returns — bool: true if the property was updated, false if
name isn’t a field object’s class declares (nothing is changed in
that case; this never creates a new field)
Raises TypeError if object isn’t an instance
Note: instances in this runtime have a fixed set of fields, sized once when their class is declared. Unlike a dict, a property can never be added to or removed from an instance at runtime. This only ever updates a field the instance’s class already declares; it can’t create a new one.
del_prop()
zuri.reflect.del_prop(object, name)
Resets object’s existing property name back to nil.
Parameters
object(instance)name(string)
Returns — bool: true if the property was reset, false if name
isn’t a field object’s class declares
Raises TypeError if object isn’t an instance
Note: as with
set_prop, this can’t remove the field itself, only clear its value; seeset_prop’s own note.
has_method()
zuri.reflect.has_method(object, name) -> bool
Does the class behind object (an instance, or a class used directly)
declare or inherit a method named name?
Parameters
object(instance|class)name(string)
Returns bool
has_decorator()
zuri.reflect.has_decorator(object, name) -> bool
Does the class behind object implement the decorator named name? A
decorator is just a method whose own name starts with @ (@to_string,
@new, @value, …); name here excludes that leading @.
Parameters
object(instance|class)name(string) — The decorator’s name, without the leading@
Returns bool
get_method()
zuri.reflect.get_method(object, name) -> ?function
The raw (unbound) closure for method name on the class behind
object, or nil if it declares no such method. Calling the result
directly does NOT supply a receiver; see bind_method for a version
that does.
Parameters
object(instance|class)name(string)
Returns ?function
bind_method()
zuri.reflect.bind_method(object, name) -> ?function
Method name on object’s class, bound to object itself as the
receiver; the result can be called directly with no receiver argument,
unlike get_method’s raw closure.
Parameters
object(instance)name(string)
Returns ?function
get_decorator()
zuri.reflect.get_decorator(object, name) -> function
The decorator function named name (excluding the leading @) on the
class behind object, bound to object as its receiver and ready to
call directly.
Parameters
object(instance)name(string) — The decorator’s name, without the leading@
Returns function
Raises NotImplementedError if the class behind object implements
no such decorator
gc()
zuri.reflect.gc() -> nil
Runs a full garbage collection now, instead of waiting for the heap to cross its threshold.
Every object nothing reaches is freed before this returns, and anything
that releases a resource when collected releases it: an owned ffi
pointer’s destructor runs, for one. The memory freed goes back to the
system before this returns too.
A program never needs this to stay correct; the collector runs on its own as the program allocates. It is for the moments the timing matters: releasing native resources at a known point, or a test that checks what collection does. A full collection visits every live object, so calling it in a loop is slow.
import zuri
var scratch = [1, 2, 3]
scratch = nil
zuri.reflect.gc()
Returns nil
2026, Richard Ore and Zuri contributors