Pular para o conteúdo

Undo/Redo e Casos Avançados

Nesta página

Viagem no tempo: :undo / :redo / :history

Cada swap bem-sucedido grava um checkpoint num ring buffer por módulo (padrão: 10 entradas). No prompt do zolo dev você pode navegar esse histórico sem reescrever o código manualmente.

Comandos disponíveis no prompt:

Comando Efeito
:undo Reverte o swap mais recente
:redo Reaplicado o último :undo
:history Lista checkpoints e contadores
:reload <modulo> Força o swap de um módulo
:eval <expr> Compila e roda uma expressão na VM viva
:stats Latências p50/p95 e contagem de swaps

O estado vivo é preservado em ambas as direções: um pub let count = 5 continua 5 após :undo, mesmo que a versão antiga tivesse o literal 0. O stack de redo é limpo quando um novo swap "fresco" acontece após um :undo.

Edite a fórmula várias vezes; use :undo/:redo para navegar entre as versões.

formula.zolo
Playground
// Feature: a perfect target to experiment with :undo / :redo

// Syntax: edit the formula multiple times; navigate the history.

// When to use: compare variants of a function without rewriting

// each one by hand. The `ReloadHistory` keeps the source of

// previous versions and re-applies them via swap.


pub fn calc(x: int) -> int {
  // Edit this formula several times during the `dev` session.

  // Each save adds a checkpoint; :undo rolls back one step.

  return x * 2
}

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

main.zolo
Playground
// Feature: time-travel of hot-reloads — :undo / :redo / :history

// Syntax: commands at the `zolo dev` prompt (not Zolo words).

// When to use: experiment with variants of a function and roll

// back to a previous one quickly without editing by hand.


use formula::{calc}

fn main() {
  print("ENTER prints calc(10). Use :undo / :redo / :history at the prompt.")
  while true {
    let line = io::read("*l")
    if line is nil || line == "q" {
      break
    }
    print("calc(10) = {calc(10)}")
  }
}

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

Reload em loop fechado sem yield

Código que nunca cede o controle (sem io::read, sem sleep) ainda recebe swaps: o hook de instrução da VM drena reloads pendentes a cada ~2000 instruções. O módulo worker.zolo pode ser editado enquanto o contador gira — a próxima chamada a tick já usa a versão nova.

Edite a mensagem em tick() enquanto o loop roda — nenhuma ação manual necessária.

worker.zolo
Playground
// Edit this while the demo is running. Save with Ctrl+S — the next

// `tick` call uses the new code with no manual intervention.


pub fn tick(i) {
  print("tick {i}: still on V1 — edit me!")
}

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

main.zolo
Playground
// Demo 02 — Hot-reload during a TIGHT CPU LOOP.

//

//   zolo dev examples/zolo_live/02_tight_loop/main.zolo

//

// This script has NO `io::read` or any other yield point. It just busies

// itself spinning a counter. Yet edits to `worker.zolo` take effect

// within milliseconds — the VM instruction hook drains pending swaps

// every ~2000 instructions, transparently to the user.

//

// While running, edit `worker.zolo` (e.g. change the message format)

// and watch the output update LIVE without any user action.


use worker::{tick}

fn main() {
  let i = 0
  let last_print = 0
  while true {
    i = i + 1
    if i - last_print > 5_000_000 {
      tick(i)
      last_print = i
    }
  }
}

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

Closures capturadas fora do live-binding

Quando uma referência de função é copiada diretamente para uma lista ou estrutura de dados (sem passar pelo thunk), o runtime ainda atualiza essa referência. Ao fazer o swap, o coletor percorre o heap e substitui cada ponteiro para a função antiga pela nova. O demo 09-closure-escape demonstra isso com um fn_queue que acumula referências a greeter.greet antes de qualquer edição:

Referências capturadas diretamente também são atualizadas no swap.

greeter.zolo
Playground
// Edit me — the queued function references in main.zolo update too,

// thanks to closure-correct hot-reload.


pub fn greet(who) {
  print("V1: hi {who}")
}

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

main.zolo
Playground
// Demo 04 — Closure-correct hot-reload.

//

//   zolo dev examples/zolo_live/04_closure_escape/main.zolo

//

// The script captures a function reference into a queue (`fn_queue`),

// then iterates and calls them. Even though the function value escapes

// the live-binding thunk, edits to greeter.zolo still take effect on

// next call: the closure registry walks the heap and patches every

// reference to the old function value with the new one.

//

// This is the deeper guarantee — works no matter how the function got

// captured.


mod greeter

fn main() {
  let fn_queue = []
  // Capture the function value DIRECTLY (no live-binding thunk):

  fn_queue.push(greeter.greet)
  fn_queue.push(greeter.greet)
  fn_queue.push(greeter.greet)

  print("Press ENTER to flush the queue — or 'q' to quit.")
  print("Edit greeter.zolo while waiting; queued fn refs update too.")
  while true {
    let line = io::read("*l")
    if line is nil || line == "q" {
      break
    }
    for f in fn_queue {
      f("queued")
    }
  }
}

Requer a CLI/host do Zolo — abra no playground ou rode localmente.

Buscar no Zolo

9 resultados

enespt-br