Skip to content

REPL

[Stabile: 2 - Stabile]

Stabile: 2 Stabilità: 2 - Stabile

Codice sorgente: lib/repl.js

Il modulo node:repl fornisce un'implementazione Read-Eval-Print-Loop (REPL) disponibile sia come programma autonomo che integrabile in altre applicazioni. È accessibile tramite:

js
import repl from 'node:repl'
js
const repl = require('node:repl')

Progettazione e funzionalità

Il modulo node:repl esporta la classe repl.REPLServer. Durante l'esecuzione, le istanze di repl.REPLServer accettano singole righe di input utente, le valutano secondo una funzione di valutazione definita dall'utente e quindi restituiscono il risultato. L'input e l'output possono provenire rispettivamente da stdin e stdout, oppure possono essere collegati a qualsiasi stream stream di Node.js.

Le istanze di repl.REPLServer supportano il completamento automatico degli input, l'anteprima del completamento, la semplice modifica della riga in stile Emacs, gli input multi-riga, la ricerca inversa i in stile ZSH, la ricerca di cronologia basata su sottostringhe in stile ZSH, l'output in stile ANSI, il salvataggio e il ripristino dello stato corrente della sessione REPL, il recupero dagli errori e le funzioni di valutazione personalizzabili. I terminali che non supportano gli stili ANSI e la modifica della riga in stile Emacs passano automaticamente a un set di funzionalità limitato.

Comandi e tasti speciali

I seguenti comandi speciali sono supportati da tutte le istanze REPL:

  • .break: durante l'inserimento di un'espressione multi-riga, immettere il comando .break (o premere Ctrl+C) per interrompere l'ulteriore input o l'elaborazione di tale espressione.
  • .clear: reimposta il context REPL a un oggetto vuoto e cancella qualsiasi espressione multi-riga in input.
  • .exit: chiude lo stream I/O, causando l'uscita del REPL.
  • .help: mostra questo elenco di comandi speciali.
  • .save: salva la sessione REPL corrente in un file: \> .save ./file/to/save.js
  • .load: carica un file nella sessione REPL corrente. \> .load ./file/to/load.js
  • .editor: entra nella modalità editor (Ctrl+D per terminare, Ctrl+C per annullare).
bash
> .editor
// Immissione modalità editor (Ctrl+D per terminare, Ctrl+C per annullare)
function welcome(name) {
  return `Hello ${name}!`;
}

welcome('Node.js User');

// Ctrl+D
'Hello Node.js User!'
>

Le seguenti combinazioni di tasti nel REPL hanno questi effetti speciali:

  • Ctrl+C: se premuto una volta, ha lo stesso effetto del comando .break. Se premuto due volte su una riga vuota, ha lo stesso effetto del comando .exit.
  • Ctrl+D: ha lo stesso effetto del comando .exit.
  • Tab: se premuto su una riga vuota, visualizza le variabili globali e locali (ambito). Se premuto durante l'inserimento di altri input, visualizza le opzioni di completamento pertinenti.

Per le associazioni di tasti relative alla ricerca inversa i, vedere reverse-i-search. Per tutte le altre associazioni di tasti, vedere associazioni di tasti TTY.

Valutazione predefinita

Per impostazione predefinita, tutte le istanze di repl.REPLServer utilizzano una funzione di valutazione che valuta le espressioni JavaScript e fornisce accesso ai moduli integrati di Node.js. Questo comportamento predefinito può essere sovrascritto passando una funzione di valutazione alternativa quando viene creata l'istanza di repl.REPLServer.

Espressioni JavaScript

Il valutatore predefinito supporta la valutazione diretta delle espressioni JavaScript:

bash
> 1 + 1
2
> const m = 2
undefined
> m + 1
3

A meno che non siano altrimenti definite all'interno di blocchi o funzioni, le variabili dichiarate implicitamente o usando le parole chiave const, let o var vengono dichiarate nell'ambito globale.

Ambito globale e locale

Il valutatore predefinito fornisce accesso a qualsiasi variabile esistente nell'ambito globale. È possibile esporre esplicitamente una variabile alla REPL assegnandola all'oggetto context associato a ciascun REPLServer:

js
import repl from 'node:repl'
const msg = 'message'

repl.start('> ').context.m = msg
js
const repl = require('node:repl')
const msg = 'message'

repl.start('> ').context.m = msg

Le proprietà nell'oggetto context appaiono come locali all'interno della REPL:

bash
$ node repl_test.js
> m
'message'

Le proprietà del contesto non sono di sola lettura per impostazione predefinita. Per specificare globali di sola lettura, le proprietà del contesto devono essere definite usando Object.defineProperty():

js
import repl from 'node:repl'
const msg = 'message'

const r = repl.start('> ')
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
})
js
const repl = require('node:repl')
const msg = 'message'

const r = repl.start('> ')
Object.defineProperty(r.context, 'm', {
  configurable: false,
  enumerable: true,
  value: msg,
})

Accesso ai moduli core di Node.js

Il valutatore predefinito caricherà automaticamente i moduli core di Node.js nell'ambiente REPL quando utilizzato. Ad esempio, a meno che non sia altrimenti dichiarato come variabile globale o in ambito, l'input fs verrà valutato on-demand come global.fs = require('node:fs').

bash
> fs.createReadStream('./some/file');

Eccezioni non intercettate globali

[Cronologia]

VersioneModifiche
v12.3.0L'evento 'uncaughtException' viene d'ora in poi attivato se la REPL viene utilizzata come programma autonomo.

La REPL utilizza il modulo domain per intercettare tutte le eccezioni non intercettate per quella sessione REPL.

Questo utilizzo del modulo domain nella REPL ha questi effetti collaterali:

Assegnazione della variabile _ (underscore)

[Cronologia]

VersioneModifiche
v9.8.0Aggiunto supporto per _error.

Il valutatore predefinito, per impostazione predefinita, assegnerà il risultato dell'espressione più recentemente valutata alla variabile speciale _ (underscore). L'impostazione esplicita di _ su un valore disabiliterà questo comportamento.

bash
> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
Assegnazione dell'espressione a _ ora disabilitata.
4
> 1 + 1
2
> _
4

Allo stesso modo, _error farà riferimento all'ultimo errore rilevato, se presente. L'impostazione esplicita di _error su un valore disabiliterà questo comportamento.

bash
> throw new Error('foo');
Errore non intercettato: foo
> _error.message
'foo'

Parola chiave await

Il supporto per la parola chiave await è abilitato al livello superiore.

bash
> await Promise.resolve(123)
123
> await Promise.reject(new Error('REPL await'))
Errore non intercettato: REPL await
    at REPL2:1:54
> const timeout = util.promisify(setTimeout);
undefined
> const old = Date.now(); await timeout(1000); console.log(Date.now() - old);
1002
undefined

Una limitazione nota dell'utilizzo della parola chiave await nella REPL è che invaliderà l'ambito lessicale delle parole chiave const e let.

Ad esempio:

bash
> const m = await Promise.resolve(123)
undefined
> m
123
> const m = await Promise.resolve(234)
undefined
> m
234

--no-experimental-repl-await disabiliterà l'await di livello superiore nella REPL.

Aggiunto in: v13.6.0, v12.17.0

La REPL supporta la ricerca inversa bidirezionale simile a ZSH. Viene attivata con Ctrl+R per cercare all'indietro e Ctrl+S per cercare in avanti.

Le voci di cronologia duplicate verranno saltate.

Le voci vengono accettate non appena viene premuto un tasto che non corrisponde alla ricerca inversa. L'annullamento è possibile premendo Esc o Ctrl+R.

Cambiare la direzione cerca immediatamente la voce successiva nella direzione prevista dalla posizione corrente.

Funzioni di valutazione personalizzate

Quando viene creato un nuovo repl.REPLServer, è possibile fornire una funzione di valutazione personalizzata. Questo può essere utilizzato, ad esempio, per implementare applicazioni REPL completamente personalizzate.

Di seguito è illustrato un esempio di una REPL che eleva al quadrato un numero dato:

js
import repl from 'node:repl'

function byThePowerOfTwo(number) {
  return number * number
}

function myEval(cmd, context, filename, callback) {
  callback(null, byThePowerOfTwo(cmd))
}

repl.start({ prompt: 'Inserisci un numero: ', eval: myEval })
js
const repl = require('node:repl')

function byThePowerOfTwo(number) {
  return number * number
}

function myEval(cmd, context, filename, callback) {
  callback(null, byThePowerOfTwo(cmd))
}

repl.start({ prompt: 'Inserisci un numero: ', eval: myEval })

Errori recuperabili

Al prompt REPL, premendo invio si invia la riga di input corrente alla funzione eval. Per supportare l'input multiriga, la funzione eval può restituire un'istanza di repl.Recoverable alla funzione di callback fornita:

js
function myEval(cmd, context, filename, callback) {
  let result
  try {
    result = vm.runInThisContext(cmd)
  } catch (e) {
    if (isRecoverableError(e)) {
      return callback(new repl.Recoverable(e))
    }
  }
  callback(null, result)
}

function isRecoverableError(error) {
  if (error.name === 'SyntaxError') {
    return /^(Unexpected end of input|Unexpected token)/.test(error.message)
  }
  return false
}

Personalizzazione dell'output REPL

Per impostazione predefinita, le istanze di repl.REPLServer formattano l'output usando il metodo util.inspect() prima di scriverlo nel flusso Writable fornito (di default process.stdout). L'opzione di ispezione showProxy è impostata su true per impostazione predefinita e l'opzione colors è impostata su true a seconda dell'opzione useColors del REPL.

L'opzione booleana useColors può essere specificata durante la costruzione per istruire lo scrittore predefinito a utilizzare codici di stile ANSI per colorare l'output del metodo util.inspect().

Se il REPL viene eseguito come programma autonomo, è anche possibile modificare le impostazioni predefinite di ispezione del REPL dall'interno del REPL usando la proprietà inspect.replDefaults che rispecchia defaultOptions da util.inspect().

bash
> util.inspect.replDefaults.compact = false;
false
> [1]
[
  1
]
>

Per personalizzare completamente l'output di un'istanza di repl.REPLServer passare una nuova funzione per l'opzione writer durante la costruzione. L'esempio seguente, ad esempio, converte semplicemente qualsiasi testo di input in maiuscolo:

js
import repl from 'node:repl'

const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter })

function myEval(cmd, context, filename, callback) {
  callback(null, cmd)
}

function myWriter(output) {
  return output.toUpperCase()
}
js
const repl = require('node:repl')

const r = repl.start({ prompt: '> ', eval: myEval, writer: myWriter })

function myEval(cmd, context, filename, callback) {
  callback(null, cmd)
}

function myWriter(output) {
  return output.toUpperCase()
}

Classe: REPLServer

Aggiunto in: v0.1.91

Le istanze di repl.REPLServer vengono create usando il metodo repl.start() o direttamente usando la parola chiave JavaScript new.

js
import repl from 'node:repl'

const options = { useColors: true }

const firstInstance = repl.start(options)
const secondInstance = new repl.REPLServer(options)
js
const repl = require('node:repl')

const options = { useColors: true }

const firstInstance = repl.start(options)
const secondInstance = new repl.REPLServer(options)

Evento: 'exit'

Aggiunto in: v0.7.7

L'evento 'exit' viene emesso quando la REPL viene chiusa ricevendo il comando .exit come input, l'utente preme + due volte per segnalare SIGINT, o premendo + per segnalare 'end' sul flusso di input. La callback dell'ascoltatore viene invocata senza alcun argomento.

js
replServer.on('exit', () => {
  console.log('Evento "exit" ricevuto dalla repl!')
  process.exit()
})

Evento: 'reset'

Aggiunto in: v0.11.0

L'evento 'reset' viene emesso quando il contesto della REPL viene ripristinato. Ciò si verifica ogni volta che il comando .clear viene ricevuto come input a meno che la REPL non utilizzi il valutatore predefinito e l'istanza repl.REPLServer sia stata creata con l'opzione useGlobal impostata su true. La callback dell'ascoltatore verrà chiamata con un riferimento all'oggetto context come unico argomento.

Questo può essere utilizzato principalmente per re-inizializzare il contesto REPL ad un certo stato predefinito:

js
import repl from 'node:repl'

function initializeContext(context) {
  context.m = 'test'
}

const r = repl.start({ prompt: '> ' })
initializeContext(r.context)

r.on('reset', initializeContext)
js
const repl = require('node:repl')

function initializeContext(context) {
  context.m = 'test'
}

const r = repl.start({ prompt: '> ' })
initializeContext(r.context)

r.on('reset', initializeContext)

Quando questo codice viene eseguito, la variabile globale 'm' può essere modificata ma poi ripristinata al suo valore iniziale usando il comando .clear:

bash
$ ./node example.js
> m
'test'
> m = 1
1
> m
1
> .clear
Clearing context...
> m
'test'
>

replServer.defineCommand(keyword, cmd)

Aggiunto in: v0.3.0

  • keyword <string> La parola chiave del comando (senza un carattere . iniziale).
  • cmd <Object> | <Function> La funzione da invocare quando il comando viene elaborato.

Il metodo replServer.defineCommand() viene utilizzato per aggiungere nuovi comandi con prefisso . all'istanza REPL. Tali comandi vengono invocati digitando un . seguito dalla keyword. Il cmd è una Function o un Object con le seguenti proprietà:

  • help <string> Testo di aiuto da visualizzare quando viene immesso .help (Opzionale).
  • action <Function> La funzione da eseguire, che accetta facoltativamente un singolo argomento stringa.

Il seguente esempio mostra due nuovi comandi aggiunti all'istanza REPL:

js
import repl from 'node:repl'

const replServer = repl.start({ prompt: '> ' })
replServer.defineCommand('sayhello', {
  help: 'Saluta',
  action(name) {
    this.clearBufferedCommand()
    console.log(`Ciao, ${name}!`)
    this.displayPrompt()
  },
})
replServer.defineCommand('saybye', function saybye() {
  console.log('Addio!')
  this.close()
})
js
const repl = require('node:repl')

const replServer = repl.start({ prompt: '> ' })
replServer.defineCommand('sayhello', {
  help: 'Saluta',
  action(name) {
    this.clearBufferedCommand()
    console.log(`Ciao, ${name}!`)
    this.displayPrompt()
  },
})
replServer.defineCommand('saybye', function saybye() {
  console.log('Addio!')
  this.close()
})

I nuovi comandi possono quindi essere utilizzati dall'interno dell'istanza REPL:

bash
> .sayhello Node.js User
Ciao, Node.js User!
> .saybye
Addio!

replServer.displayPrompt([preserveCursor])

Aggiunto in: v0.1.91

Il metodo replServer.displayPrompt() prepara l'istanza REPL per l'input dell'utente, stampando il prompt configurato su una nuova riga nell'output e riprendendo l'input per accettare nuovi input.

Quando viene immesso un input multi-riga, viene stampato un'ellissi anziché il 'prompt'.

Quando preserveCursor è true, il posizionamento del cursore non verrà ripristinato a 0.

Il metodo replServer.displayPrompt è principalmente destinato ad essere chiamato dall'interno della funzione di azione per i comandi registrati utilizzando il metodo replServer.defineCommand().

replServer.clearBufferedCommand()

Aggiunto in: v9.0.0

Il metodo replServer.clearBufferedCommand() cancella qualsiasi comando che è stato bufferizzato ma non ancora eseguito. Questo metodo è principalmente destinato ad essere chiamato dall'interno della funzione di azione per i comandi registrati utilizzando il metodo replServer.defineCommand().

replServer.setupHistory(historyPath, callback)

Aggiunto in: v11.10.0

Inizializza un file di registro della cronologia per l'istanza REPL. Quando si esegue il binario Node.js e si utilizza il REPL della riga di comando, un file di cronologia viene inizializzato per impostazione predefinita. Tuttavia, questo non è il caso quando si crea un REPL a livello di programmazione. Utilizzare questo metodo per inizializzare un file di registro della cronologia quando si lavora con istanze REPL a livello di programmazione.

repl.builtinModules

Aggiunto in: v14.5.0

Un elenco dei nomi di tutti i moduli Node.js, ad esempio, 'http'.

repl.start([options])

[Cronologia]

VersioneModifiche
v13.4.0, v12.17.0L'opzione preview è ora disponibile.
v12.0.0L'opzione terminal ora segue la descrizione predefinita in tutti i casi e useColors controlla hasColors() se disponibile.
v10.0.0La modalità REPL_MAGIC_MODE replMode è stata rimossa.
v6.3.0L'opzione breakEvalOnSigint è ora supportata.
v5.8.0Il parametro options è ora opzionale.
v0.1.91Aggiunto in: v0.1.91
  • options <Oggetto> | <stringa>

    • prompt <stringa> Il prompt di input da visualizzare. Predefinito: '\> ' (con uno spazio finale).

    • input <stream.Readable> Lo stream Readable da cui verrà letto l'input REPL. Predefinito: process.stdin.

    • output <stream.Writable> Lo stream Writable in cui verrà scritto l'output REPL. Predefinito: process.stdout.

    • terminal <booleano> Se true, specifica che l'output deve essere trattato come un terminale TTY. Predefinito: verifica il valore della proprietà isTTY sullo stream output al momento dell'istanza.

    • eval <Funzione> La funzione da utilizzare per valutare ogni riga di input fornita. Predefinito: un wrapper asincrono per la funzione JavaScript eval(). Una funzione eval può generare un errore con repl.Recoverable per indicare che l'input era incompleto e richiedere ulteriori righe.

    • useColors <booleano> Se true, specifica che la funzione writer predefinita dovrebbe includere la formattazione a colori ANSI nell'output REPL. Se viene fornita una funzione writer personalizzata, ciò non ha alcun effetto. Predefinito: verifica il supporto del colore sullo stream output se il valore terminal dell'istanza REPL è true.

    • useGlobal <booleano> Se true, specifica che la funzione di valutazione predefinita utilizzerà il global JavaScript come contesto invece di creare un nuovo contesto separato per l'istanza REPL. Il REPL della CLI di node imposta questo valore su true. Predefinito: false.

    • ignoreUndefined <booleano> Se true, specifica che lo scrittore predefinito non emetterà il valore restituito di un comando se questo viene valutato come undefined. Predefinito: false.

    • writer <Funzione> La funzione da invocare per formattare l'output di ogni comando prima di scriverlo su output. Predefinito: util.inspect().

    • completer <Funzione> Una funzione opzionale utilizzata per il completamento automatico della tabulazione personalizzato. Vedere readline.InterfaceCompleter per un esempio.

    • replMode <simbolo> Un flag che specifica se il valutatore predefinito esegue tutti i comandi JavaScript in modalità strict o predefinita (sloppy). I valori accettabili sono:

    • repl.REPL_MODE_SLOPPY per valutare le espressioni in modalità sloppy.

    • repl.REPL_MODE_STRICT per valutare le espressioni in modalità strict. Questo equivale a premettere ogni istruzione repl con 'use strict'.

    • breakEvalOnSigint <booleano> Interrompere la valutazione del codice corrente quando si riceve SIGINT, ad esempio quando si preme + . Questo non può essere utilizzato insieme a una funzione eval personalizzata. Predefinito: false.

    • preview <booleano> Definisce se il repl stampa anteprime di completamento automatico e output o meno. Predefinito: true con la funzione eval predefinita e false nel caso in cui venga utilizzata una funzione eval personalizzata. Se terminal è falso, non ci sono anteprime e il valore di preview non ha effetto.

  • Restituisce: <repl.REPLServer>

Il metodo repl.start() crea e avvia un'istanza repl.REPLServer.

Se options è una stringa, specifica il prompt di input:

js
import repl from 'node:repl'

// un prompt in stile Unix
repl.start('$ ')
js
const repl = require('node:repl')

// un prompt in stile Unix
repl.start('$ ')

La REPL di Node.js

Node.js stesso usa il modulo node:repl per fornire una propria interfaccia interattiva per l'esecuzione di JavaScript. Questo può essere utilizzato eseguendo il binario Node.js senza passare alcun argomento (o passando l'argomento -i):

bash
$ node
> const a = [1, 2, 3];
undefined
> a
[ 1, 2, 3 ]
> a.forEach((v) => {
...   console.log(v);
...   });
1
2
3

Opzioni delle variabili d'ambiente

Vari comportamenti della REPL di Node.js possono essere personalizzati usando le seguenti variabili d'ambiente:

  • NODE_REPL_HISTORY: Quando viene fornito un percorso valido, la cronologia REPL persistente verrà salvata nel file specificato anziché in .node_repl_history nella home directory dell'utente. Impostando questo valore su '' (una stringa vuota) verrà disabilitata la cronologia REPL persistente. Gli spazi bianchi verranno rimossi dal valore. Su piattaforme Windows le variabili d'ambiente con valori vuoti non sono valide, quindi impostare questa variabile su uno o più spazi per disabilitare la cronologia REPL persistente.
  • NODE_REPL_HISTORY_SIZE: Controlla quante righe di cronologia verranno mantenute se la cronologia è disponibile. Deve essere un numero positivo. Default: 1000.
  • NODE_REPL_MODE: Può essere 'sloppy' o 'strict'. Default: 'sloppy', che consentirà l'esecuzione di codice in modalità non rigorosa.

Cronologia persistente

Per impostazione predefinita, la REPL di Node.js manterrà la cronologia tra le sessioni REPL di node salvando gli input in un file .node_repl_history situato nella home directory dell'utente. Questo può essere disabilitato impostando la variabile d'ambiente NODE_REPL_HISTORY=''.

Utilizzo della REPL di Node.js con editor di riga avanzati

Per editor di riga avanzati, avviare Node.js con la variabile d'ambiente NODE_NO_READLINE=1. Questo avvierà la REPL principale e del debugger nelle impostazioni del terminale canoniche, che consentiranno l'utilizzo con rlwrap.

Ad esempio, quanto segue può essere aggiunto a un file .bashrc:

bash
alias node="env NODE_NO_READLINE=1 rlwrap node"

Avvio di più istanze REPL su una singola istanza in esecuzione

È possibile creare ed eseguire più istanze REPL su una singola istanza di Node.js in esecuzione che condividono un singolo oggetto global ma hanno interfacce I/O separate.

L'esempio seguente, ad esempio, fornisce REPL separate su stdin, un socket Unix e un socket TCP:

js
import net from 'node:net'
import repl from 'node:repl'
import process from 'node:process'

let connections = 0

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout,
})

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via Unix socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen('/tmp/node-repl-sock')

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via TCP socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen(5001)
js
const net = require('node:net')
const repl = require('node:repl')
let connections = 0

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout,
})

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via Unix socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen('/tmp/node-repl-sock')

net
  .createServer(socket => {
    connections += 1
    repl
      .start({
        prompt: 'Node.js via TCP socket> ',
        input: socket,
        output: socket,
      })
      .on('exit', () => {
        socket.end()
      })
  })
  .listen(5001)

L'esecuzione di questa applicazione dalla riga di comando avvierà una REPL su stdin. Altri client REPL possono connettersi tramite il socket Unix o il socket TCP. telnet, ad esempio, è utile per la connessione a socket TCP, mentre socat può essere utilizzato per connettersi sia a socket Unix che TCP.

Avviando una REPL da un server basato su socket Unix anziché da stdin, è possibile connettersi a un processo Node.js a lunga durata senza riavviarlo.

Per un esempio di esecuzione di una REPL "a funzionalità complete" (terminal) su un'istanza net.Server e net.Socket, vedere: https://gist.github.com/TooTallNate/2209310.

Per un esempio di esecuzione di un'istanza REPL su curl(1), vedere: https://gist.github.com/TooTallNate/2053342.

Questo esempio è destinato puramente a scopo didattico per dimostrare come le REPL di Node.js possono essere avviate utilizzando diversi flussi I/O. Non dovrebbe essere utilizzato in ambienti di produzione o in qualsiasi contesto in cui la sicurezza è una preoccupazione senza ulteriori misure protettive. Se è necessario implementare REPL in un'applicazione reale, prendere in considerazione approcci alternativi che mitighi questi rischi, come l'utilizzo di meccanismi di input sicuri e l'evitare le interfacce di rete aperte.