Script Runner (onion)¶
The onion command compiles and executes Onion source files directly in memory, without creating .class files.
Usage¶
Options¶
-classpath <classpath>¶
Set the classpath for compilation and execution.
-encoding <encoding>¶
Specify the character encoding of source files.
-maxErrorReports <count>¶
Limit the number of compilation errors reported.
--dump-ast¶
Print the parsed AST to stderr before running the script.
--dump-typed-ast¶
Print a typed AST summary (classes, fields, methods) to stderr before running the script.
--profile-compile¶
Emit a compile profile before the script is executed.
--profile-format <text|json>¶
Choose text or JSON profile output.
--profile-output <target>¶
Write the compile profile to stderr, stdout, or a file path.
onion --profile-compile --profile-format json \
--profile-output target/script-profile.json \
MyScript.on
--warn <off|on|error>¶
Control warning reporting. error treats warnings as compilation errors.
--Wno <codes>¶
Suppress specific warning categories by code or name.
Program Arguments¶
Arguments after the source file(s) are passed to your program:
Access them in your code:
class MyScript {
public:
static def main(args :String[]): void {
foreach arg :String in args {
println("Argument: " + arg)
}
}
}
Entry Point¶
The script runner determines the entry point automatically:
1. Explicit Main Method¶
If a class has a main method, it's used as the entry point:
class MyProgram {
public:
static def main(args :String[]): void {
println("Hello from main method")
}
}
2. First Class with Main¶
If multiple classes have main methods, the first one is used:
class First {
public:
static def main(args :String[]): void {
println("This will run")
}
}
class Second {
public:
static def main(args :String[]): void {
println("This won't run")
}
}
3. Top-Level Declarations and Expressions¶
If there's no explicit main method, the first top-level declaration or expression is the entry point:
println("Hello, World!")
val x: Int = 10
println("x = " + x)
// These block elements execute immediately
Examples¶
Simple Script¶
hello.on:
Run:
With Arguments¶
greet.on:
class Greeter {
public:
static def main(args :String[]): void {
if args.length > 0 {
println("Hello, " + args[0] + "!")
} else {
println("Hello, stranger!")
}
}
}
Run:
Quick Calculations¶
calc.on:
Run:
File Processing¶
count_lines.on:
import {
java.io.BufferedReader;
java.io.FileReader;
}
class LineCounter {
public:
static def main(args :String[]): void {
if args.length == 0 {
println("Usage: onion count_lines.on <filename>")
return
}
val filename: String = args[0]
val reader: BufferedReader = new BufferedReader(
new FileReader(filename)
)
var count: Int = 0
var line: String = null
while (line = reader.readLine()) != null {
count = count + 1
}
reader.close()
println("Lines: " + count)
}
}
Run:
In-Memory Compilation¶
The onion command:
- Compiles source files to bytecode
- Loads classes into memory
- Executes the entry point
- No
.classfiles are created
This is ideal for: - Quick scripts - Testing code snippets - Automation tasks - One-off programs
Multiple Source Files¶
Compile and run multiple files:
All files are compiled together, and the entry point is determined from the first file.
Error Handling¶
Compilation Errors¶
Runtime Errors¶
$ onion runtime_error.on
Exception in thread "main" java.lang.ArithmeticException: / by zero
at RuntimeError.main(runtime_error.on:10)
Comparison with onionc¶
| Feature | onion | onionc |
|---|---|---|
| Creates .class files | No | Yes |
| Execution | Immediate | Requires java command |
| Use case | Scripts, testing | Production, libraries |
| Speed | Fast for small programs | Better for repeated runs |
| Distribution | Requires source | Can distribute .class/.jar |
Scripting Best Practices¶
Shebang Line (Unix-like systems)¶
Make scripts executable:
hello.on:
Make executable:
Error Messages¶
Provide helpful error messages:
class Script {
public:
static def main(args :String[]): void {
if args.length < 2 {
println("Error: Missing arguments")
println("Usage: onion script.on <input> <output>")
return
}
// Process arguments...
}
}
Exit Codes¶
Return appropriate exit codes:
class Script {
public:
static def main(args :String[]): void {
if args.length == 0 {
System::exit(1) // Error
}
// Success
System::exit(0)
}
}
Next Steps¶
- Compiler (onionc) - Compile to class files
- REPL Shell - Interactive programming
- Examples - Example scripts