New Features
Signal handling (signal)
A new stdlib module for responding to OS signals β catch Ctrl-C to shut down cleanly, reload configuration on SIGHUP, and more:
use "signal"
signal.on("INT", fn()
puts "shutting down..."
exit(0)
end)
puts "running β press Ctrl-C to stop"
signal.wait()Handlers are race-free: they run on the goroutine that calls signal.wait(), so they never run concurrently with the rest of your program and can't corrupt shared state. A handler that doesn't exit simply returns, and wait() keeps listening β perfect for "reload" signals:
signal.on("HUP", fn()
puts "reloading configuration"
end)Supported signals: INT, TERM, HUP, QUIT, USR1, USR2, WINCH, PIPE, and ALRM (the SIG prefix is optional and names are case-insensitive).
Functions:
signal.on(name, handler)β register a handlersignal.wait()β block and dispatch handlers as signals arrivesignal.reset(name)β stop invoking a handlersignal.ignore(name)β ignore a signal entirely
See docs/modules/signal.md for the full reference and examples/signal.rugo for a working tour.
Improvements
Stronger type checking
The type annotation system introduced in v0.29.0 now catches more mistakes at compile time:
Missing return values β typed functions that can fall off the end without returning are flagged:
def lookup(id : Integer) : String
if id > 0
return "found"
end
# error: function 'lookup' declared returning String may end without a return value
endLossy numeric coercions β passing a Float where an Integer is expected (or vice versa when precision would be lost) is now an error:
def count(n : Integer)
puts n
end
count(3.7)
# error: cannot pass Float literal as argument 1 to 'count'Compound assignment defaults β type mismatches in parameter defaults (e.g. def f(x : Integer = "oops")) are caught.
Lambda variable bindings β annotated lambdas assigned to variables are now checked at their call sites:
add = fn(a : Integer, b : Integer) : Integer
return a + b
end
add("x", 1)
# error: cannot pass String literal as argument 1String and Bool returns β returning the wrong type from a function declared : String or : Bool is now caught, matching the Integer/Float checks from v0.29.0.
CLI -- passthrough
The cli module now properly handles -- as a separator between flags and passthrough arguments, making it easy to wrap other commands:
use "cli"
cli.name("wrapper")
cli.run(fn()
extra = cli.passthrough()
# everything after -- lands here
end)Heredocs in expressions
Heredocs can now appear in expression positions (assignments, function arguments), not just as standalone statements.
Bug Fixes
returnoutside a function β now produces a clear error message instead of a confusing Go compilation failure.nil + stringcoercion β addingnilto a string now raises an error instead of silently producing"<nil>".- Error messages include filename β
invalid tokenerrors now show the source file path, making them actionable in multi-file projects.