Script mode (rat run)
rat run script.rat [args...] executes a single .rat file's > main[args] against the same eval engine the dev server uses. No HTTP, no page render, no client. Use it for seed scripts, one-off data fixes, CLI utilities, and anything that wants Rat's dispatch and builtins without starting a browser.
Hello, args
Positional CLI args land as a Rat array
The script declares > main[args]. args is a Rat array of strings; the CLI command and the script path are stripped before binding, so rat run hello.rat one two hands main ['one', 'two']. << N returns the exit code.
> main[args]
log('hello from rat run', args)
<< 0 Output (stdout):
hello from rat run [one, two] Exit codes via <<
main returns an int; rat exits with it
Any integer returned via << becomes the process exit code (clamped to a byte). A non-int return, or no return at all, falls through to 0. Use this to signal pass or fail to whatever shell or CI step invoked the script.
> main[args]
(len(args) == 0)
error('usage: rat run check.rat <name>')
<< 2
log('checking', args[0])
<< 0 log vs error
stdout and stderr, as in any CLI tool
In script mode log(...) and debug(...) write to stdout; error(...) writes to stderr. Pipe stdout to a log file while errors still show on the terminal, exactly as you'd expect from a normal CLI tool.
> main[args]
log('processing', len(args), 'items')
[a] in args
(a == '')
error('skipping empty arg')
log(' ->', upper(a))
<< 0 Server state + helper functions
Available in scripts, without the page tiers
Top-level > server declarations and > name[params] functions are available to main, exactly like a page handler. Use them to factor a script the same way you'd factor a page: state at the top, helpers below, main at the bottom.
> server
greeting: 'hi'
> shout[s] >> upper(s)
> main[args]
log(shout(greeting), '- args:', args)
<< 0 Services work too
Singletons hold state across calls inside one script run
A > service [name] declared in the script is a singleton for that run. Methods share their state frame, and reads from outside the service see the live values. Put a counter, a registry, or any other state you need to carry across helpers into a service and call it the usual way.
> service [counter]
n: 0
bump[]
n << n + 1
<< n
> main[args]
log(counter.bump()) # 1
log(counter.bump()) # 2
<< 0 Tiers not allowed in scripts
page, session, and local need a client
Script mode rejects > page, > session, and > local declarations at load with a script-mode hint. These tiers exist because a browser is on the other end of the connection; without one, there is nothing to react against. Move shared state to > server or a service.
Two example scripts live under site/scripts/ in the source tree: hello.rat is the smallest possible script, and seed_users.rat shows args parsing, a helper function, a stateful service, and a usage-or-exit path. Run them from the project root with rat run scripts/hello.rat alpha beta and rat run scripts/seed_users.rat alice bob.