> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ubiquex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Built-in Functions

> 30 built-in functions for string, collection, type conversion, numeric, encoding, and IP/CIDR operations.

ubx provides 30 built-in functions usable in any attribute expression. When any argument is `Pending&lt;T&gt;`, the result is automatically wrapped in `.apply()`.

## Interactive Testing

```bash theme={null}
ubx console
> lower("HELLO")
"hello"
> cidrsubnet("10.0.0.0/16", 8, 2)
"10.0.2.0/24"
```

## String Functions

| Function                | Description      | Example                               |
| ----------------------- | ---------------- | ------------------------------------- |
| `lower(s)`              | Lowercase        | `lower("PROD")` → `"prod"`            |
| `upper(s)`              | Uppercase        | `upper("dev")` → `"DEV"`              |
| `replace(s, old, new)`  | Replace all      | `replace("a-b", "-", "_")` → `"a_b"`  |
| `trim(s)`               | Strip whitespace | `trim("  x  ")` → `"x"`               |
| `trimprefix(s, prefix)` | Remove prefix    | `trimprefix("pre-x", "pre-")` → `"x"` |
| `trimsuffix(s, suffix)` | Remove suffix    | `trimsuffix("x-suf", "-suf")` → `"x"` |
| `split(sep, s)`         | Split to list    | `split(",", "a,b")` → `["a","b"]`     |
| `join(sep, list)`       | Join list        | `join("-", ["a","b"])` → `"a-b"`      |
| `format(fmt, ...args)`  | sprintf          | `format("%s-%s", "a", "b")` → `"a-b"` |
| `strlen(s)`             | Length           | `strlen("hello")` → `5`               |

## Collection Functions

| Function                | Description    | Example                                    |
| ----------------------- | -------------- | ------------------------------------------ |
| `length(list)`          | Count items    | `length(["a","b"])` → `2`                  |
| `keys(obj)`             | Object keys    | `keys({a="1"})` → `["a"]`                  |
| `values(obj)`           | Object values  | `values({a="1"})` → `["1"]`                |
| `merge(obj1, obj2)`     | Merge objects  | `merge({a="1"},{b="2"})` → `{a="1",b="2"}` |
| `contains(list, val)`   | Membership     | `contains(["a","b"],"a")` → `true`         |
| `lookup(obj, key, def)` | Key + fallback | `lookup({a="1"},"b","x")` → `"x"`          |
| `flatten(list)`         | Flatten nested | `flatten([["a"],["b"]])` → `["a","b"]`     |
| `distinct(list)`        | Remove dupes   | `distinct(["a","a","b"])` → `["a","b"]`    |

## Type Conversion

| Function      | Description | Example                 |
| ------------- | ----------- | ----------------------- |
| `tostring(v)` | To string   | `tostring(42)` → `"42"` |
| `tonumber(v)` | To number   | `tonumber("42")` → `42` |
| `tobool(v)`   | To boolean  | `tobool(1)` → `true`    |

## Numeric Functions

| Function    | Description    | Example            |
| ----------- | -------------- | ------------------ |
| `min(a, b)` | Smaller        | `min(3, 5)` → `3`  |
| `max(a, b)` | Larger         | `max(3, 5)` → `5`  |
| `abs(n)`    | Absolute value | `abs(-7)` → `7`    |
| `ceil(n)`   | Round up       | `ceil(1.3)` → `2`  |
| `floor(n)`  | Round down     | `floor(1.9)` → `1` |

## Encoding Functions

| Function          | Description   | Example                               |
| ----------------- | ------------- | ------------------------------------- |
| `jsonencode(v)`   | To JSON       | `jsonencode({a="1"})` → `'{"a":"1"}'` |
| `jsondecode(s)`   | Parse JSON    | `jsondecode("{}")` → `{}`             |
| `base64encode(s)` | Base64 encode | `base64encode("hi")` → `"aGk="`       |
| `base64decode(s)` | Base64 decode | `base64decode("aGk=")` → `"hi"`       |

## IP/CIDR Functions

| Function                      | Description   | Example                                             |
| ----------------------------- | ------------- | --------------------------------------------------- |
| `cidrsubnet(cidr, bits, idx)` | Subnet CIDR   | `cidrsubnet("10.0.0.0/16", 8, 1)` → `"10.0.1.0/24"` |
| `cidrhost(cidr, idx)`         | Host IP       | `cidrhost("10.0.0.0/24", 5)` → `"10.0.0.5"`         |
| `cidrnetmask(cidr)`           | Netmask       | `cidrnetmask("10.0.0.0/24")` → `"255.255.255.0"`    |
| `cidrprefix(cidr)`            | Prefix length | `cidrprefix("10.0.0.0/24")` → `24`                  |

## `Pending&lt;T&gt;` Propagation

```hcl theme={null}
# Resolved — emitted inline
bucket = lower("PROD")
# → ("PROD").toLowerCase()

# Pending — single arg wraps in .apply()
bucket = lower(~unit.aws_s3_bucket_v2.src.bucket)
# → src.bucket.apply(_dep0 => (_dep0).toLowerCase())

# Multiple pending args — uses pulumi.all()
bucket = join("-", [~unit.x.y.name, ~unit.z.w.id])
# → pulumi.all([x.name, z.id]).apply(([_dep0, _dep1]) => [_dep0, _dep1].join("-"))
```
