Al momento stai visualizzando JShell Tutorial

JShell Tutorial

Premessa

Questo tutorial è estratto dall’approfondimento del capitolo 4.1 del mio libro “Il Nuovo Java”.

È possibile scaricare gratuitamente tale approfondimento insieme a tanto altro materiale (circa 1000 pagine) dell’espansione online del libro “Il Nuovo Java” all’indirizzo https://www.nuovojava.it.

 

1.1 JShell

Una delle novità più interessanti che ha portato con sé Java 9, non riguarda il linguaggio, ma il JDK. Infatti è stata aggiunta alla suite di applicazioni storiche come java, javadoc, javac, etc., la console JShell. Si tratta di un software della tipologia REPL, acronimo di Read-Evaluate-Print Loop, che possiamo tradurre come ciclo leggi-valuta-stampa. Infatti un software REPL è implementato di solito come una console interattiva, che quando attivata apre un loop (ciclo) con cui si mette in attesa di input da parte dell’utente. Ad ogni input che viene confermato dall’utente il software lo legge, lo valuta e stampa un risultato. Ma a cosa serve JShell?

Per testare come funziona una certa parte di codice, solitamente dobbiamo scrivere un programma intero, che come minimo richiede l’esecuzione di una classe che contiene il metodo main (ma di solito anche la compilazione). Poi bisogna risolvere eventuali errori ripetendo il ciclo scrivi(-compila)-esegui-valuta, tante volte fino a quando non risolveremo ogni problema.

Con JShell è possibile scrivere vari tipi di snippet come statement, espressioni, metodi, variabili, classi, import e così via, senza dover obbligatoriamente scrivere le espressioni nei metodi, o i metodi nelle classi o scrivere un metodo main. Non è nemmeno necessario compilare: ogni input passato a JShell viene immediatamente letto e valutato, quindi viene stampato un messaggio di risposta sulla valutazione. Non ci sarà neanche bisogno di usare obbligatoriamente i comandi di stampa come abbiamo fatto sinora. JShell ci permetterà di risparmiare tempo e ci invoglierà a sperimentare più facilmente il nostro codice, a creare prototipi, scoprire le librerie standard come funzionano davvero ed altro ancora. Può quindi accelerare il processo di apprendimento.

JShell non sostituisce un IDE, ma è possibile copiare il codice da un IDE e incollarlo in JShell per semplificarne il test. Naturalmente è possibile anche copiare il codice da JShell per incollarlo all’interno di un IDE.

Nel momento in cui stiamo scrivendo, abbiamo verificato che le versioni di Java successive alla 11 (comprese la 17) JShell non riconoscono la pressione di alcune combinazioni di tasti, come quelle che usiamo di scrivere le parentesi graffe. Per tale ragione, per gli esempi di questo tutorial abbiamo usato la versione del JDK 11.

 

1.1.1 HelloWorld con JShell

Per aprire una sessione con JShell, è necessario semplicemente aprire una prompt dei comandi (programma cmd), e da lì eseguire il comando:

jshell

(è possibile anche eseguire direttamente il comando jshell dal menu Start di Windows, senza aprire prima la prompt dei comandi).

JShell ci darà il benvenuto e ci inviterà ad eseguire un comando per ottenere ulteriori informazioni. Digitando quindi il comando suggerito:

/help intro

JShell ci descriverà come funziona in breve, mostrando anche qualche semplice esempio, come è possibile osservare nella figura 1.

Figura 1 – Apertura sessione JShell ed esecuzione comando “/help intro”.

Nel messaggio di introduzione viene subito fatta una distinzione tra i comandi di JShell (per esempio /help intro) e i cosiddetti snippet (ovvero i frammenti di codice Java che JShell legge, valuta e stampa). I comandi JShell iniziano tutti con il simbolo /, e possiamo leggerne la lista completa digitando semplicemente il comando:

/help

oppure più brevemente:

/?

Invece possiamo scrivere qualsiasi istruzione Java all’interno di una sessione JShell e lasciarla processare premendo il tasto Enter (Invio). Per esempio possiamo stampare al volo la stringa Hello World! nel seguente modo:

jshell> System.out.println("Hello World!")

ed ottenere la risposta:

Hello World!

Si noti che non c’è stato neanche bisogno di utilizzare il “;” finale, che in Java caratterizza tutti gli statement. Questo perché JShell, come vedremo nel prossimo paragrafo, ha regole meno restrittive rispetto al classico compilatore Java.

Se digitassimo il nostro codice scorrettamente:

jshell> System.out.PRINTLN("Hello World!")

otterremo un errore da JShell:

|  Error:
|  cannot find symbol
|    symbol:   method PRINTLN(java.lang.String)
|  System.out.PRINTLN("Hello World!")
|  ^----------------^

Per uscire da una sessione JShell (ed essere salutati), basta digitare il comando:

jshell> /exit
|  Goodbye

 

1.1.2 JShell e codice Java

Abbiamo visto che all’interno di una sessione JShell è possibile alternare codice Java (snippet, classi, metodi, e così via) e comandi JShell. Per quanto riguarda il codice Java, JShell si pone l’obiettivo di rappresentare uno strumento per testarlo nel modo più veloce possibile. Come abbiamo già notato non occorre creare per forza classi, metodi e seguire tutte le classiche regole di Java, bensì tale strumento cerca di facilitare la codifica e quindi ci sono alcune regole un po’ diverse rispetto a quelle classiche. Partiamo subito con degli esempi.

Consigliamo al lettore di scrivere le istruzioni seguenti passo dopo passo per familiarizzare con JShell. Tra un esempio e l’altro potrà anche testare altre istruzioni. Si può anche tranquillamente lavorare con due sessioni JShell separate.

 

1.1.2.1 Esempi pratici

La prima regola che cambia l’abbiamo già notata: con le espressioni su di un’unica riga non c’è bisogno di utilizzare il “;” finale. Possiamo quindi dichiarare una variabile intera uno, inizializzata con il valore 1 nel seguente modo:

jshell> int uno = 1
uno ==> 1

Si noti come JShell abbia restituito la valutazione dello snippet stampando a video:

uno ==> 1

che va interpretato come “la variabile uno vale 1”. Ora dichiariamo una variabile booleana senza inizializzarla:

jshell> boolean b
b ==> false

In questo caso la variabile booleana b è automaticamente inizializzata al suo valore di default false (come una variabile d’istanza quando viene istanziato un oggetto). Possiamo quindi già notare la seconda regola differente rispetto al compilatore Java, che riguarda l’inizializzazione delle variabili. Le variabili degli snippet non inizializzate sono automaticamente impostate ai propri valori nulli, come se fossero variabili d’istanza. Se proviamo a dichiarare un’altra variabile con lo stesso nome della precedente (b) nel seguente modo:

jshell> boolean b
b ==> false

JShell non avrà problemi ad utilizzarla. Infatti la nuova dichiarazione della variabile b va a sovrascrivere la precedente dichiarazione. All’interno di codice Java ordinario, questa situazione avrebbe provocato un errore in compilazione, perché non si possono dichiarare due variabili con lo stesso nome. Quindi ecco una terza regola differente per JShell rispetto al compilatore Java: dichiarare due volte la stessa variabile (o lo stesso metodo) causa la sovrascrittura della prima variabile dichiarata (o del primo metodo dichiarato). Nella programmazione standard questa situazione provocherebbe un errore in compilazione. Anche in questo caso non avendo fornito un’inizializzazione alla variabile b, viene assegnato automaticamente il valore nullo per il tipo di dato, che per un tipo byte equivale a 0. Assegniamo poi il valore 128 alla variabile b. Ricordiamo che il valore massimo che può assumere un tipo di dato byte è 127, quindi otterremo un errore:

jshell> b = 128
|  Error:
|  incompatible types: possible lossy conversion from int to byte
|  b = 128
|      ^-^

I messaggi di JShell seguono sempre un simbolo di “|” (in inglese si legge “pipe”).

Quindi forziamo l’assegnazione con un cast a byte:

jshell> b = (byte)128
b ==> -128

Come spiegato nel capitolo 3, il valore 128 immagazzinato nella variabile byte b, diventa -128. A causa del troncamento dei primi 24 bit della rappresentazione binaria di 128. Proviamo quindi a sottrarre un’unità al numero che doveva essere 128 e che invece risulta essere rappresentato in un byte come -128, e assegniamolo nuovamente alla variabile b. Anche in questo caso bisogna ricorrere al cast visto che un’espressione tra un tipo byte e un tipo int (la sottrazione b-uno) restituisce un risultato di tipo intero:

jshell> b = (byte)(b-uno)
b ==> 127

Il valore è ora correttamente immagazzinato nella variabile byte. Adesso eseguiamo il comando di stampa sommando b e di nuovo la variabile uno:

jshell> System.out.print(b+uno)
128

Questa volta viene stampato il valore corretto, visto che b+uno, è un’espressione tra un byte ed un int, e quindi il risultato viene promosso ad int, e 128 è un valore rappresentabile come tipo int.

Notare che abbiamo invocato il metodo print sull’oggetto System.out, invece del più usato metodo println. La differenza risiede nel fatto che println stampa il valore in input e poi va a capo (“println” è l’abbreviativo di “print line”). Nel nostro esempio era inutile andare a capo e quindi ne abbiamo approfittato per introdurre il metodo print.

Possiamo anche definire classi, enumerazioni, annotazioni ed anche metodi isolati, che probabilmente non sarà possibile scrivere su di un’unica riga come gli snippet scritti sinora. Ogni volta che andiamo a capo JShell, a meno di errori di sintassi, non valuterà quanto abbiamo scritto, ma aspetterà il completamento della struttura dati che stiamo definendo. Dobbiamo tener conto che per i tipi Java (classi, interfacce, record, enumerazioni ed annotazioni) non innestati saranno ignorati tutti i modificatori (tranne abstract), e che non è possibile dichiarare package o moduli. Infine, se chiamiamo un metodo che non abbiamo ancora definito, JShell ci avvertirà con un warning, ma ci consentirà di andare avanti considerando valido il nostro codice.

 

1.1.2.2 Sommario delle regole di JShell

Scrivere codice in JShell, presenta quindi alcune differenze rispetto a scriverlo all’interno di classi Java. Queste differenze hanno lo scopo di semplificare l’esperienza di codifica, ma contemporaneamente pongono anche dei limiti alla programmazione. Riassumiamo di seguito le principali differenze.

  • Benché sia possibile dichiarare metodi, non è richiesto obbligatoriamente dichiararne uno per scrivere uno statement.
  • Benché sia possibile dichiarare classi, non è richiesto obbligatoriamente dichiararne una per scrivere metodi o variabili.
  • Se scriviamo statement in un’unica linea, non è necessario utilizzare il simbolo “;”.
  • Non è possibile dichiarare package (cfr. capitolo 5) o moduli (cfr. capitolo 16).
  • Per tutti i tipi non innestati (cfr. modulo 13), tutti i modificatori fondamentali, a parte abstract (cfr. capitolo 6), sono ignorati o non permessi da JShell.
  • La parola chiave synchronized (cfr. capitolo 12) è sempre ignorata.
  • Dichiarare due volte la stessa variabile (o lo stesso metodo) causa la sovrascrittura della prima variabile dichiarata (o del primo metodo dichiarato); nella programmazione standard questa situazione provocherebbe un errore in compilazione.
  • Dichiarare in uno snippet una variabile senza inizializzarla, implica che essa sia automaticamente inizializzata al proprio valore nullo.

 

1.1.3 Comandi JShell

I comandi JShell si distinguono dal codice Java perché sono sempre preceduti dal prefisso /. Sino ad ora abbiamo eseguito solo due comandi: il comando /help (equivalente a /?) ed il comando /exit. Cerchiamo di fare una breve panoramica dei comandi principali di JShell.

1.1.3.1 Comandi esplorativi

Proviamo ad eseguire il comando /history:

jshell> /history

int uno = 1
boolean b
byte b
b = 128
b = (byte)128
b = (byte)(b-uno)
System.out.print(b+uno)
/history

Questo comando ci mostra la storia di tutto quello che abbiamo digitato in questa sessione (sia snippet che comandi JShell). Se invece siamo interessati solo agli snippet possiamo utilizzare il comando /list:

jshell> /list

   1 : int uno = 1;
   3 : byte b;
   4 : b = (byte)128
   5 : b = (byte)(b-uno)
   6 : System.out.println(b+uno)

Viene mostrato un elenco numerato degli snippet validi che abbiamo eseguito. Ogni snippet ha il suo snippet id (numero identificatore). Come si può notare manca lo snippet id 2, dove avevamo dichiarato b come variabile booleana, ma che poi abbiamo sovrascritto con la definizione di b come variabile byte (snippet id 3). Non è stato riportato neanche lo snippet che ha provocato un errore. Notiamo inoltre come solo per gli snippet id 1 e 3 sia stato aggiunto il simbolo “;”. Questo perché JShell evidenzia il “;” solo quando si tratta di una dichiarazione. Gli snippet id possono essere richiamati con la sintassi:

/snippetId

Se richiamassimo uno snippet id relativo ad una dichiarazione di una variabile, essa verrà ridichiarata sovrascrivendo il valore che aveva assunto precedentemente. Il comando /help
eseguito senza aggiungere opzioni elenca tutti i possibili comandi che possiamo eseguire con una breve spiegazione. È possibile invece avere qualche dettaglio in più su come funzionano i vari comandi facendo seguire al comando /help il nome del comando JShell di cui si desiderano le informazioni. In generale quindi possiamo digitare:

/help nomeComando

Per esempio:

jshell> /help /list
|
|  /list
|
|  Show the source of snippets, prefaced with the snippet id.
|
|  /list
|       List the currently active snippets of code that you 
  typed or read with /open
|
|  /list -start
|       List the automatically evaluated start-up snippets
|
|  /list -all
|       List all snippets including failed, overwritten, dropped, 
  and start-up
|
|  /list <name>
|       List snippets with the specified name (preference for 
  active snippets)
|
|  /list <id>
|       List the snippet with the specified snippet id

Scopriamo così che è possibile passare delle opzioni al comando /list. In particolare per vedere tutti i dettagli della nostra sessione, compresi gli snippet non validi e le istruzioni che ha implicitamente aggiunto JShell, possiamo eseguire il comando /list -all:

jshell> /list -all

  s1 : import java.io.*;
  s2 : import java.math.*;
  s3 : import java.net.*;
  s4 : import java.nio.file.*;
  s5 : import java.util.*;
  s6 : import java.util.concurrent.*;
  s7 : import java.util.function.*;
  s8 : import java.util.prefs.*;
  s9 : import java.util.regex.*;
 s10 : import java.util.stream.*;
   1 : int uno = 1;
   2 : boolean b;
   3 : byte b;
  e1 : b = 128
   4 : b = (byte)128
   5 : b = (byte)(b-uno)
   6 : System.out.println(b+uno)

Da questo output possiamo capire varie cose. Per esempio che JShell importa alcune librerie automaticamente per semplificarci la vita. Infatti esiste uno script di startup che importa automaticamente le librerie listate nell’esempio precedente e che viene eseguito quando parte la sessione di JShell. Le librerie sono identificate con un id composto dalla lettera “s” (iniziale di “start”) e un numero sequenziale, ovvero s1, s2, s3, etc. Vedremo nel paragrafo successivo come sia possibile cambiare queste impostazioni. Se vogliamo vedere solo i package importati possiamo usare il comando:

jshell> /list -start

oppure il comando /imports:

jshell> /imports

che non ci mostrerà la numerazione s1, s2, s3, etc. accanto ad ogni istruzione di import. La differenza tra i due comandi risiede soprattutto nel fatto che quest’ultimo riporterà anche altre eventuali istruzioni di import digitate come snippet, mentre il primo riporterà solo gli import inclusi di default.

Possiamo anche notare che in questo output è presente anche lo snippet con id 2, anche se è stato sovrascritto dallo snippet con id 3. Inoltre viene listata anche l’istruzione (b = 128) che ha causato l’errore, a cui stato assegnato lo snippet id e1 (la lettera “e” sta per “error”). I comandi /types, /vars e /methods, hanno la stessa funzione di /list, ovvero quella di elencare quanto già digitato. La differenza è che il comando /types mostra solo i tipi dichiarati (classi interfacce, annotazioni, record ed enumerazioni), il comando /methods mostra solo i metodi dichiarati (non quelli dichiarati nelle classi), il comando /vars mostra solo le variabili dichiarate (non quelle dichiarate nelle classi e nei metodi). Questi comandi condividono le stesse opzioni del comando /list: per esempio -all per vedere tutte le occorrenze valide e non valide (di tipi, variabili, metodi), -start per vedere cosa appartiene allo script di partenza della sessione (di tipi, variabili, metodi), oppure è possibile specificare lo snippet id o il nome (di tipi, variabili, metodi).

 

1.1.3.2 Comandi esecutivi

Abbiamo già asserito che esiste uno script di startup che importa automaticamente alcuni package, e che esso viene eseguito quando parte la sessione di JShell. In particolare abbiamo visto che di default JShell esegue uno script che importa i più comuni package (vedi esempio precedente).

Tale lista di import può essere configurata mediante il comando /set start; sono già disponibili tre configurazioni diverse, ma è anche possibile crearne di nuove. Oltre alla configurazione di default (che si chiama appunto DEFAULT), esistono altre due configurazioni predefinite: JAVASE e PRINTING. Con il comando:

jshell> /set start -retain PRINTING

otterremo che sarà impostato come script di startup per le prossime sessioni lo script PRINTING.

Se non specifichiamo l’opzione -retain, lo script di startup non sarà mantenuto per le prossime sessioni.

Se vogliamo applicare lo script impostato nella sessione corrente da subito, dobbiamo eseguire il comando /reload, che rilancia anche tutte le istruzioni valide eseguite nella sessione. Lo script PRINTING metterà a disposizione dei metodi con nomi brevi per la stampa, e potremo usare in luogo di System.out.println, System.out.print e System.out.printf, rispettivamente i metodi println, print e printf.

Il terzo script JAVASE invece importa tutti i package possibili di Java Standard Edition. In questo modo non saremo obbligati a importare mai nulla, ma dovremo aspettare qualche secondo in più prima che parta JShell. È possibile anche impostare più di uno script di startup alla volta, per esempio:

jshell> /set start -retain DEFAULT PRINTING

Per impostare script personalizzati invece, possiamo scrivere:

jshell> /set start -retain C:/MiaCartella/MioScript

Oppure andare a scrivere in un file l’attuale configurazione di startup con il comando /save:

jshell> /save -start C:/MiaCartella/MioScript

Con il comando /save possiamo anche salvare in un file altre informazioni. Per esempio possiamo salvare tutta la lista delle istruzioni valide che abbiamo digitato con:

jshell> /save C:/MiaCartella/MioScript

oppure tutta la lista delle istruzioni valide e non valide:

jshell> /save -all C:/MiaCartella/MioScript

oppure tutta la history della sessione corrente:

jshell> /save -history C:/MiaCartella/MioScript

Con il comando /open invece, possiamo aprire un file precedentemente salvato. Si può trattare anche di un file .java. Per esempio:

jshell> /open C:/MiaCartella/HelloWorld.java

Con /env possiamo impostare la variabile CLASSPATH per farla puntare a qualche libreria (file .jar), con la sintassi:

jshell> /env –class-path C:/MiaCartella/MiaLibreria.jar

I concetti di CLASSPATH (introdotto nel primo capitolo) e file JAR, sono presentati all’interno dell’appendice E.

Con /env è possibile anche impostare il cosiddetto MODULEPATH, che però sarà argomento dell’ultimo modulo di questo libro.

Il comando /drop può eliminare uno snippet, specificando il suo nome o il suo id.

Con il comando /reset invece, il comando /list sarà ripulito di tutte le istruzioni eseguite. Il comando /history invece continuerà a funzionare come funzionava precedentemente l’esecuzione del comando /reset.

È possibile richiamare l’ultima riga (valida o non valida) editata anche con il comando /!.

 

1.1.4 Strumenti ausiliari di JShell

Siccome JShell viene eseguito all’interno di una prompt DOS, è possibile sfruttarne alcune comodità. Per esempio possiamo richiamare precedenti righe digitate anche usando il tasto di Freccia Su ↑ (e tornare indietro con il tasto Freccia Giù ↓). È possibile anche copiare, incollare e ricercare mediante le funzionalità della prompt DOS, come descritto nell’appendice C.

Ma questi non sono gli unici aiuti di cui si può usufruire utilizzando JShell.

 

1.1.4.1 Variabili implicite

JShell assegna un reference o una variabile primitiva implicitamente, nel caso non ne assegniamo noi una esplicitamente, deducendone il tipo automaticamente. Si parla di variabili implicite con tipo dedotto (implicit variables with type inferred). Per esempio, se scriviamo:

jshell> 1
$1 ==> 1

possiamo notare che a 1 viene assegnata implicitamente la variabile intera $1 (il tipo dedotto automaticamente). Possiamo richiamare la variabile ed utilizzarla, per esempio:

jshell> $1 + $1
$2 ==> 2

si noti come sia stata creata anche una seconda variabile implicita ($2).

 

1.1.4.2 Forwarding reference

Abbiamo già asserito che possiamo dichiarare anche tipi o metodi, e che magari possiamo anche copiarli in JShell a partire da codice già scritto. In casi come questi potrebbe capitare di invocare metodi, o utilizzare classi, non ancora definiti. Per esempio, se dichiarassimo un reference di una classe non ancora dichiarata:

jshell> Utente u;
|  created variable u, however, it cannot be referenced until 
  class Utente is declared

 

JShell la creerebbe, ma ci avvertirebbe che non sarà possibile utilizzarla fin quando la classe Utente non sarà dichiarata. Se creassimo la classe Utente successivamente:

jshell> class Utente {}
|  created class Utente
|    update replaced variable u, reset to null

la variabile u sarebbe inizializzata al suo valore di default (null). Un discorso simile si ripete se proviamo a chiamare un metodo non ancora definito:

jshell> void testForward() {
   ...> stampa();
   ...> }
|  created method testForward(), however, it cannot be invoked 
  until method stampa() is declared

 

1.1.4.3 Auto-completamento

Il tasto TAB, può essere utilizzato per l’auto-completamento, sia per snippet che per comandi JShell. Per esempio, se dopo aver scritto Strin battiamo il tasto TAB, otterremo il seguente output:

jshell> Strin
String                            StringBuffer
StringBufferInputStream           StringBuilder
StringIndexOutOfBoundsException   StringJoiner
StringReader                      StringTokenizer
StringWriter
jshell> String

Quindi ci vengono proposte tutte le possibili opzioni per completare il nostro codice, ma intanto viene scelto quello più probabile. TAB può essere usato ogni volta che si vuole un aiuto o che si vuole esplorare una particolare classe, libreria o metodo, e anche un comando JShell. Con una doppia pressione del tasto TAB si ottiene la documentazione ufficiale dell’ultima dichiarazione, da scorrere pagina dopo pagina sempre con il tasto TAB.

Un altro ausilio per completare automaticamente il nostro codice, JShell ce lo offre con un’insolita combinazione di tasti. Per importare automaticamente una classe non ancora importata per esempio, bisogna prima utilizzare tale classe. Poi premere contemporaneamente i tasti SHIFT e TAB, rilasciarli e dopo premere il tasto i (che sta per “import”). Per esempio, se utilizziamo questa combinazione di tasti dopo aver digitato:

jshell> new JButton

allora JShell ci proporrà di scegliere tra gli import possibili o di non fare niente (opzione 0):

0: Do nothing
1: import: javax.swing.JButton
Choice:
Imported: javax.swing.JButton

Oppure, se dopo aver dichiarato un valore, vogliamo dichiarare un reference (o una variabile primitiva) basterà semplicemente premere contemporaneamente i tasti SHIFT e TAB, rilasciarli, quindi premere il tasto v (che sta per “variable”). JShell dedurrà il tipo della variabile, la dichiarerà e posizionerà il cursore subito dopo per permetterci di definire il reference. Infatti dopo aver istanziato un Integer, utilizzando la suddetta combinazione di tasti otteniamo:

jshell> new Integer(1);
jshell> Integer = new Integer(1);

dove il cursore è posizionato prima del simbolo =. Non ci resta che scrivere il nome del reference e confermare:

jshell> Integer intero = new Integer(1);
intero ==> 1

 

1.1.4.4 Il comando /edit

Il comando /edit apre un semplice editor chiamato JShell Edit Pad (vedi figura 2), che in alcuni casi (come nei copia-incolla) semplifica lo sviluppo del codice.

Figura 2 – JShell Edit Pad in azione.

Tutto quello che scriveremo in JShell Edit Pad, può essere riportato al volo su JShell facendo clic sul bottone Accept (JShell si aggiornerà contestualmente con i nuovi valori editati), oppure sarà riportato automaticamente dopo che si è chiuso JShell Edit Pad facendo clic sul bottone Exit.

Cancellare istruzioni già presenti non significa eliminarle come se si stesse usando il comando /drop. Semplicemente non le vedremo nell’editor.

Le modifiche saranno ignorate se facciamo clic su Cancel.

Se vogliamo sfruttare un altro editor più completo (per esempio Notepad++) è possibile impostarlo come default per la sessione corrente (per l’impostazione permanente utilizzare l’opzione -retain) con il comando /set:

jshell> /set editor C:\Program Files (x86)\Notepad++\notepad++.exe
|  Editor set to: C:\Program Files (x86)\Notepad++\notepad++.exe

Salvando il file in Notepad++, otterremo lo stesso effetto del bottone Accept di JShell Edit Pad. Con il comando /set è possibile anche configurare altre funzionalità. Per esempio, con l’opzione feedback, è possibile aumentare la verbosità dei messaggi di analisi specificando il valore verbose (saranno descritte testualmente le operazioni eseguite), oppure diminuirla specificando il valore coincise (saranno stampati solo i risultati delle operazioni e non delle dichiarazioni), o evitarli del tutto con il comando silent. Per i più esigenti esistono anche le opzioni, mode, format, prompt e truncation, per personalizzare ulteriormente JShell. Si rimanda alla documentazione (comando /help) se si è interessati a questi dettagli.

 

1.1.4.5 Scorciatoie da tastiera (shortcuts)

JShell offre alcune scorciatoie da tastiera, in inglese shortcuts (ovvero combinazioni di tasti) per automatizzare dei comandi predefiniti. Segue una tabella esplicativa dei comandi disponibili (i tasti vanno premuti contemporaneamente):

Shortcut Descrizione
CTRL a Sposta il cursore all’inizio della riga
CTRL e Sposta il cursore alla fine della riga
ALT b Sposta il cursore un carattere indietro
ALT f Sposta il cursore un carattere avanti
CTRL b Sposta il cursore all’inizio della parola precedente
CTRL f Sposta il cursore all’inizio della parola successiva
CTRL r Esegue una ricerca dell’ultimo comando o snippet che contiene i caratteri digitati subito dopo CTRL r
CTRL t Scambia i due caratteri alla sinistra del cursore
CTRL w Cancella la parola alla sinistra del cursore
ALT d Cancella la parola alla destra del cursore
CTRL k Cancella tutto quanto è alla destra del cursore fino alla fine della riga
CTRL u Cancella tutto quanto è alla sinistra del cursore fino alla fine della riga

 

Lascia un commento