First locate the broken boundary: ingest IR, typed/lowered IR, emitted source,
or the running program. Build the relevant tool once or invoke it with
cargo run --bin <name> --.
roundhouse-ast exposes Prism, template
compilation, ingest, and Ruby expression emission:
cargo run --bin roundhouse-ast -- --help
cargo run --bin roundhouse-ast -- -e '[:a, :b]'
cargo run --bin roundhouse-ast -- --stage prism -e '@x.y do end'
cargo run --bin roundhouse-ast -- --stage compile-erb view.html.erb
cargo run --bin roundhouse-ast -- --stage emit-ruby -e '"a#{x}b"'
cargo run --bin roundhouse-ast -- --stages --erb -e '<%= x %>'
cargo run --bin roundhouse-ast -- --round-trip -e '[:a, :b]'A positional .rb/.erb file replaces -e; .erb selects template mode.
IR stages print JSON. --round-trip accepts plain Ruby only and compares
ingest → emit-ruby → ingest IR; it does not prove whole-app source equality
or runtime correctness. On divergence it prints both IRs and a diff.
dump_ir analyzes and lowers a fixture before
dumping the shape consumed by application emitters. Narrow it to the failing
class/method rather than reading the entire app:
cargo run --bin dump_ir -- --help
cargo run --bin dump_ir -- fixtures/real-blog --select 'ArticlesController#create'
cargo run --bin dump_ir -- fixtures/real-blog --format json --select Article--raw-views instead shows pre-lowering view bodies. Use the same selector
as the failing regression to distinguish a wrong lowering from a wrong emitter.
emit_preview is a narrow bench/browser
debugging tool. It analyzes source IR directly and emits bare files, not
the complete packaged application or the shared post-analyze lowering path:
cargo run --bin emit_preview -- --target rust --out /tmp/rh-preview fixtures/real-blogIt has no --help; its source lists supported targets and TypeScript profiles.
It replaces the output directory, so use a disposable path. For normal
application assembly, including Ruby/Spinel, use bin/rh transpile <target>.
bin/rh compare <target> drives Rails and the emitted server together.
The raw comparator is a standalone crate, not a root
Cargo binary. Using it on your own app: the compare guide.
Do not mask a genuine translation bug as a variable value.
To see compiler phase wall times and process peak RSS:
ROUNDHOUSE_TIMINGS=1 cargo test --test emit_and_run the_unedited_blog_runs -- --nocaptureTiming is opt-in; a process high-water RSS is not per-phase allocated memory.
On Linux each line also reports the current anonymous RSS (rss anon),
which leaves out file-backed pages.
To see what holds the heap, build with the memory-census feature. Each
timing line then adds the exact live heap, its high-water mark over the
run so far (live peak), and the high-water mark within that phase or
lap alone (phase peak), so a late phase's own cost shows even when an
earlier phase peaked higher. ROUNDHOUSE_MEMORY_CENSUS=1 prints the
size of every App field, the body/header split of the unit
collections, IR node counts and the analyzer's fields after ingest,
analysis, the post-analyze lowerings and emit:
cargo build --bin roundhouse --features memory-census
scripts/synth-app /tmp/synth --packs 50
ROUNDHOUSE_TIMINGS=1 ROUNDHOUSE_MEMORY_CENSUS=1 \
target/debug/roundhouse --target ruby --survey --allow-unsupported -o /tmp/synth-out /tmp/synthscripts/memory-budget checks two such runs, on two sizes of
scripts/synth-app, and fails when the peak, or its growth per pack,
exceeds ci/memory-budget.json. A change that lowers memory updates the
budget with scripts/memory-budget --record; raising it needs a reason in
the PR.
ROUNDHOUSE_STORE=spill keeps library method bodies in a file (the unit
store, src/store.rs) while the analysis fixpoint runs: the library pass
writes each class's bodies there once it has typed them, and a body that
anything reads again is decoded on that read. Output is the same either
way; only memory and time change. The file goes in ROUNDHOUSE_STORE_DIR
(the system temp directory otherwise), which must not be tmpfs.
ROUNDHOUSE_STORE=check also round-trips every record as it is written.
Other debugging controls are discoverable at their readers:
rg -n 'ROUNDHOUSE_' src/ scripts/. Matches include comments and generated
code; inspect the actual read before assuming a variable is live.