Rat docs

Inspection

Five builtins for asking values about themselves. len counts, type labels, keys and values unpack objects, has checks membership. They work uniformly on strings, arrays, and objects — the same call gives the right answer regardless of shape.

len — count anything countable

Strings, arrays, objects all work

len(value) returns the size. For strings it's the byte length, for arrays the element count, for objects the key count. Calling it on a number, bool, or null is an error — use the value directly if that's what you want.

<p> [len('abc')]
<p> [len(items)]
<p> [len(person)]
Result

string: 3

array: 3

object: 2

type — the runtime kind

One of: null, bool, int, float, string, array, object, function

type(value) returns the kind as a string. Useful for branching on shape in a function that accepts a few possibilities. Note int and float are distinct — the server tier preserves the distinction even though they're both number in the browser.

<p> [type('hi')]
<p> [type(42)]
<p> [type(3.14)]
<p> [type(true)]
<p> [type(items)]
<p> [type(person)]
<p> [type(null)]
Result

'hi' → string

42 → int

3.14 → float

true → bool

items → array

person → object

null → null

keys — list the field names

Insertion order, as written in the source

keys(obj) returns the field names in the order they were declared. Pair with in keys(obj) to iterate. Calling it on an array returns the integer indices as strings.

<p> [keys(person)]

<ul>
    [k] in keys(person)
        <li> [k]
Result

[first, last]

  • first
  • last

values — list the field values

Same order as keys; pairs by index

values(obj) returns the values in the same order keys would. Zip them together when you need [k, v] pairs.

<p> [values(person)]
Result

[Grace, Hopper]

has — membership test

true / false; works on objects, arrays, strings

has(obj, name) returns whether the key exists on the object. On arrays it tests element membership; on strings it tests substring presence. contains is its alias for arrays and strings — use whichever reads better in context.

<p> [has(person, 'first')]
<p> [has(person, 'age')]
<p> [has(items, 'pears')]
<p> [has('hello world', 'lo wo')]
Result

person.first exists? true

person.age exists? false

items has 'pears'? false

'hello world' has 'lo wo'? false

Putting them together

A generic dispatch table by type

Combine type with a guard chain to render different markup per kind. The same trick works for sanitising user input or normalising heterogenous data into a uniform shape before storage.

> render_value[v]
    (type(v) == 'array')
        <ul>
            [x] in v
                <li> [x]
    (type(v) == 'object')
        <dl>
            [k] in keys(v)
                <dt> [k]
                <dd> [v[k]]
    (else)
        <p> [v]

Next: Strings — case, trim, split, join, replace, padding, and friends.