Lua runner with rich builtin stdlib ("lunascript")
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
luna/docs/os.md

3.5 KiB

os

Luna runs scripts in a sandbox, so the standard os table is trimmed to its safe, time-related functions — os.time, os.clock, os.date, os.difftime — while the parts that touch the system (os.execute, os.getenv, os.remove, os.exit, …) are removed. To that trimmed table Luna adds a high-resolution clock, an async sleep, and access to the script's command-line arguments.

local t0 = os.microtime()
os.sleep(0.25)
print(string.format("waited %.3fs", os.microtime() - t0))  --> waited ~0.250s

os.microtime()

Return the current time as a Unix timestamp in seconds, as a float with sub-second precision — unlike os.time, which is whole seconds only. It is the right tool for measuring elapsed time:

local start = os.microtime()
doSomeWork()
local elapsed = os.microtime() - start
log.info(string.format("took %.1f ms", elapsed * 1000))

It reads the system wall clock, so it tracks real time (and can jump if the clock is adjusted); for interval timing the difference of two readings is what you want.

os.args()

Return the command-line arguments passed to the script, as an array (a fresh table on every call, so it is safe to mutate). On the luna command line the script's arguments are everything after the script path — even a token spelled like a luna flag goes to the script there, so luna's own flags (--sandbox & co.) must come before the path. A -- between the path and the arguments is accepted and skipped:

luna script.lua one two --three
luna --sandbox script.lua -- one two --three
-- script.lua
for i, arg in ipairs(os.args()) do
    print(i, arg)  --> 1 one / 2 two / 3 --three
end

An executable script with a #!/usr/bin/env luna shebang line receives its arguments the same way, with no -- needed:

./script.lua one two --three

In the REPL os.args() returns an empty table. Arguments are passed through as raw byte strings, without UTF-8 conversion.

os.sleep(seconds)

Pause for seconds (a float, so os.sleep(0.1) is 100 ms). This is an async sleep: it suspends the script on the runtime instead of blocking the OS thread, so concurrent work keeps running while it waits.

os.sleep(1)      -- one second
os.sleep(0.05)   -- 50 milliseconds

seconds must be a non-negative finite number.

Because the sleep suspends rather than blocks, sibling tasks started with task.join make progress during the wait — that is what lets several sleeps (or requests, or queries) overlap:

-- finishes in ~0.3s, not 0.6s — the sleeps overlap
task.join(
    function() os.sleep(0.3) end,
    function() os.sleep(0.2) end,
    function() os.sleep(0.1) end
)

One caveat applies to coroutines you drive yourself with coroutine.wrap / coroutine.resume: there, os.sleep does not actually wait. See Self-driven coroutines for the full explanation — the rule is to run anything that needs to sleep through task.join.

Notes

  • The sandbox keeps the time functions. os.time, os.clock, os.date, and os.difftime work as in stock Lua; functions that touch the system are not present.
  • microtime for durations, time for timestamps. Use os.microtime when you need sub-second precision or are timing an interval; os.time when whole seconds suffice.
  • sleep is cooperative. It yields to the runtime, so it is cheap to sleep inside concurrent tasks — see Concurrency.