Capy-Bearer Documentation

unit_load

host call

Capy

function unit_load(path : string) module

Description

unit_load() loads a unit and returns a handle you can call exported functions on. It is the way one unit calls another unit's code, as opposed to component(), which renders another unit's output.

The target unit publishes names with #exports or an EXPORT_ function prefix. A callable export has the exact signature (any) any. Exported type metadata is not a callable function.

Calling through the handle

Two spellings do the same thing. Member syntax is the readable one:

var target := unit_load("/doc/examples/call_target.capy")
var result := target.echo(name: "Ada")
print(result.name, "\n")

Output

Ada

call() is the explicit form. Use call(target, name, input) or target.call(name, input) when the function name is a value:

var target := unit_load("/doc/examples/call_target.capy")
var result := call(target, "echo", name: "Ada")
print(result.name, "\n")

Output

Ada

Every callable export takes exactly one any input and returns an any. Omitting the input at the call passes an empty map. The exported function still declares its input parameter.

When to load a handle, and when not to

Load a handle once and reuse it when several calls hit the same unit — the handle carries the resolved, compiled unit, so repeat calls skip the lookup.

For a target chosen at runtime, unit_call("path:name", input) makes one call without keeping a handle. For a fixed target, prefer #import "path" as alias. The compiler checks alias.export(input) against the exported name and signature.

What a handle is

A module value is opaque: there is nothing inside it to read, print, or compare. It is request-local — a handle is valid for the request that created it and cannot be stored and reused later. Pass it through typed module parameters within the request. A handle cannot enter an any value.

Values crossing a call are the same objects on both sides: the callee receives the value you passed in, and the result it returns is what you get.

Loading and rendering

Loading runs the unit's initializers and INIT once in the current workspace. It does not call RENDER, COMPONENT, or ONCE. An exported function call does not run ONCE either. Use a render or component call when you need the unit's output.

An exported function can still use print. That output goes into the caller's current output buffer. Its return value is separate from printed output.

Related entry points

unit_render() runs a unit's RENDER handler and writes its output to the response. unit_info() reports a unit's exports and compile state; unit_compile() compiles a unit without calling it.

Parameters

path : the unit path to load

Return Values

A module handle for the unit.

Errors

A path that does not resolve, a unit that fails to compile, or a name the target does not export raises a runtime error that aborts the request. Use unit_info() first when a unit's availability is genuinely optional.

Example

Capy

var target := unit_load("/doc/examples/call_target.capy")
print(target.default_input(), "\n")

Output

default

Example

Capy

var target := unit_load("/doc/examples/call_target.capy")
print(target.echo(name: "Ada").name, "\n")
print(target.echo(name: "Grace").name, "\n")

Output

Ada
Grace

Example

Capy

var target := unit_load("/doc/examples/call_target.capy")
var wanted := "echo"
print(target.call(wanted, name: "Katherine").name, "\n")

Output

Katherine