Skip to content

v0.30.0

Latest

Choose a tag to compare

@github-actions github-actions released this 03 Jul 11:25
Immutable release. Only release title and notes can be modified.

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 handler
  • signal.wait() β€” block and dispatch handlers as signals arrive
  • signal.reset(name) β€” stop invoking a handler
  • signal.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
end

Lossy 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 1

String 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

  • return outside a function β€” now produces a clear error message instead of a confusing Go compilation failure.
  • nil + string coercion β€” adding nil to a string now raises an error instead of silently producing "<nil>".
  • Error messages include filename β€” invalid token errors now show the source file path, making them actionable in multi-file projects.