Προγραμματισμός

Τι σημαίνει REPL για Java

Ίσως είστε προγραμματιστής Clojure ή Scala, ή ίσως έχετε συνεργαστεί με το LISP στο παρελθόν. Εάν ναι, υπάρχει μια καλή πιθανότητα να χρησιμοποιήσετε ένα REPL ως μέρος της καθημερινής σας ρουτίνας. ΑΠΑΝΤΗΣΗ, ή read-eval-print-loop, είναι μια διεπαφή κελύφους που διαβάζει κάθε γραμμή εισόδου, αξιολογεί αυτήν τη γραμμή και, στη συνέχεια, εκτυπώνει το αποτέλεσμα. Άμεση ανατροφοδότηση, ωραία!

Όταν χρησιμοποιείτε ένα REPL, γράφετε κώδικα διαδραστικά και τον εκτελείτε χωρίς καθυστέρηση. Η κυκλοφορία του Java 9 το 2016 θα προσφέρει ένα πλήρως λειτουργικό περιβάλλον REPL με το όνομα JShell (με κωδικό όνομα Kulla). Αυτό το άρθρο παρέχει μια επισκόπηση της Java REPL και συζητά ορισμένες δυνατότητες για το πώς θα μπορούσατε να τη χρησιμοποιήσετε στον προγραμματισμό Java - ναι, εσείς!

Περιμένετε, η Java δεν έχει ήδη REPL;

Σίγουρα μια καθιερωμένη γλώσσα όπως η Java πρέπει να έχει REPL! Λοιπόν, στην πραγματικότητα, δεν έχουν όλες οι γλώσσες και η Java είναι μία από αυτές που την έλειπαν. Αναμφισβήτητα, με περισσότερη τελετή και βραχίονα από τις περισσότερες γλώσσες, η Java είναι μία από τις γλώσσες των οποίων οι προγραμματιστές την άξιζαν περισσότερο. Η Java είχε κάτι λίγο σαν REPL για λίγο με τη μορφή Java BeanShell, αλλά αυτό το έργο δεν ήταν ποτέ ένα πλήρως χαρακτηρισμένο REPL σε σύγκριση με εκείνο άλλων γλωσσών. Ήταν απλώς ένα υποσύνολο της πλήρους σύνταξης γλώσσας Java.

Το REPL μειώνει την ανακύκλωση

Η μείωση του χρόνου ανακύκλωσης και των βρόχων ανατροφοδότησης όσο το δυνατόν περισσότερο είναι εξαιρετικά σημαντική για τη λογική ενός προγραμματιστή. Το REPL είναι ένα εξαιρετικό εργαλείο για προγραμματιστές που θέλουν να επιτύχουν ακριβώς αυτό. Οι προγραμματιστές είναι πιο παραγωγικοί όταν μπορούν να δουν τα αποτελέσματα της εργασίας τους αμέσως. Με ένα Java REPL, οι προγραμματιστές θα μπορούν να γράφουν κώδικα, να εκτελούν αυτόν τον κώδικα και, στη συνέχεια, να συνεχίζουν να εξελίσσουν τον κώδικά τους εν κινήσει χωρίς να χρειάζεται να βγούν για να εκτελέσουν μια έκδοση και ούτω καθεξής. Ενώ πολλά από τα συστήματα που χρησιμοποιούν Java είναι πέρα ​​από την πολυπλοκότητα αυτού που θα μπορούσε να αντιμετωπιστεί από μια διαδραστική REPL, η απλή παρουσία ενός REPL στο JDK σημαίνει ότι κάποιος, κάπου θα βρει μια καταπληκτική περίπτωση χρήσης για αυτό σε χρόνο μηδέν. Το γεγονός ότι το JShell εκθέτει ένα API ουσιαστικά διασφαλίζει ότι οι προγραμματιστές IDE πρόκειται να ενσωματώσουν αυτό το REPL στα εργαλεία που χρησιμοποιούμε για τη σύνταξη κώδικα. Απλά περιμένετε μέχρι το Java REPL να είναι μέρος κάθε IDE!

Ξεκινήστε με το JShell

Είναι σημαντικό να συνειδητοποιήσετε ότι η χρήση του REPL-in-development, Project Kulla, δεν είναι για εξασθενημένη καρδιά. Κούλα, γνωστός Το JShell, δεν αποτελεί μέρος του πακέτου προεπισκόπησης JDK 9 κατά τη στιγμή της σύνταξης, οπότε θα πρέπει να κλωνοποιήσετε ένα έργο Mercurial, να συντάξετε το JDK και να συντάξετε τον εαυτό σας JShell. Αφιερώστε μια ώρα για αυτήν τη διαδικασία, ειδικά εάν δεν πετάτε συνήθως τον πηγαίο κώδικα JDK. Θα πρέπει να απενεργοποιήσετε τις προειδοποιήσεις ως σφάλματα, και εάν δημιουργείτε OSX βεβαιωθείτε ότι έχετε εγκαταστήσει το XCode μαζί με το XQuartz για τη βιβλιοθήκη freetype. Ακολουθήστε τις παρακάτω οδηγίες για να εγκαταστήσετε και να εκτελέσετε το Project Kulla στο περιβάλλον ανάπτυξης Java.

1. Εγκαταστήστε το Java 9

Για να εκτελέσετε το JShell θα χρειαστεί να κατεβάσετε και να εγκαταστήσετε την πιο πρόσφατη έκδοση προεπισκόπησης πρώιμης πρόσβασης για το Java 9. Μόλις κατεβάσετε το Java 9, ορίστε το JAVA_HOME μεταβλητή περιβάλλοντος και εκτέλεση java –μετατροπή για να επαληθεύσετε την εγκατάστασή σας. Αυτό μπορεί να είναι πόνος, ειδικά στο OSX, οπότε αξίζει τον διπλό έλεγχο!

2. Εγκαταστήστε το Mercurial και το Project Kulla

Το Project Kulla είναι ένα έργο OpenJDK, οπότε θα πρέπει να κλωνοποιήσετε το αποθετήριο Mercurial για να το μεταγλωττίσετε.

Στη συνέχεια θα κλωνοποιήσετε το αποθετήριο Kulla:

 hg κλώνος //hg.openjdk.java.net/kulla/dev kulla 

Στη συνέχεια, θα διαμορφώσετε το build:

 cd kulla bash ./configure --disable-Warnings-as-σφάλμα κάνει εικόνες 

3. Μεταγλώττιση και εκτέλεση REPL

Εδώ είναι ο κωδικός για τη μεταγλώττιση του REPL:

 cd langtools / repl; bash ./scripts/compile.sh 

Και εδώ είναι ο κωδικός για να το εκτελέσετε:

 bash ./scripts/run.sh 

Όπως σημείωσα, το χαρακτηριστικό REPL της Java δεν είναι ακόμη έτοιμο για γενική κατανάλωση, αλλά μπορούμε ακόμα να το πάρουμε για πρόωρη δοκιμαστική μονάδα!

Κάνεις τα μαθηματικά

Για ένα αρχικό παράδειγμα του τι μπορεί να κάνει το JShell, ας αξιολογήσουμε μερικές απλές εκφράσεις χρησιμοποιώντας java.lang.Math:

Λίστα 1. Αξιολόγηση μαθηματικών εκφράσεων με REPL

 $ bash ./scripts/run.sh | Καλώς ήλθατε στο JShell - Έκδοση 0.710 | Πληκτρολογήστε / βοήθεια για βοήθεια -> Math.sqrt (144.0f); | Η τιμή έκφρασης είναι: 12.0 | εκχωρήθηκε σε προσωρινή μεταβλητή $ 1 του τύπου double -> 1 $ + 100; | Η τιμή έκφρασης είναι: 112.0 | εκχωρήθηκε σε προσωρινή μεταβλητή $ 2 τύπου double -> / vars | διπλά $ 1 = 12,0 | διπλό $ 2 = 112,0 -> διπλό val = Math.sqrt (9000); | Προστέθηκε μεταβλητή val τύπου διπλού με αρχική τιμή 94.86832980505137 

Εδώ αξιολογούμε τις εκφράσεις, βρίσκουμε την τετραγωνική ρίζα ενός αριθμού και στη συνέχεια προσθέτουμε δύο αριθμούς μαζί. Αυτός δεν είναι ο πιο περίπλοκος κώδικας, αλλά πρέπει να σημειώσετε ότι το / vars Η εντολή μας δίνει τη δυνατότητα να παραθέσουμε τις μεταβλητές που δημιουργήθηκαν στην περίοδο λειτουργίας JShell. Μπορούμε να αναφερθούμε σε τιμές μη εκχωρημένων εκφράσεων χρησιμοποιώντας τη σημείωση του δολαρίου ($). Τέλος, μπορούμε να δημιουργήσουμε μια νέα μεταβλητή και να της εκχωρήσουμε μια τιμή.

Ορίστε μια μέθοδο

Τώρα γίνεται πιο ενδιαφέρον. Σε αυτό το παράδειγμα ορίζουμε μια μέθοδο για τον υπολογισμό της ακολουθίας Fibonacci. Αφού οριστεί η μέθοδος, ελέγχουμε για να δούμε ποιες μεθόδους ορίζονται με το / μέθοδοι εντολή. Τέλος, εκτελούμε ένα απόσπασμα κώδικα για να βρούμε έναν πίνακα και να εκτυπώσουμε τους πρώτους αριθμούς της ακολουθίας.

Λίστα 2. Υπολογίστε την ακολουθία Fibonacci

 $ bash ./scripts/run.sh | Καλώς ήλθατε στο JShell - Έκδοση 0.710 | Τύπος / βοήθεια για βοήθεια -> long fibonacci (long number) >> if ((number == 0) | Προστέθηκε μέθοδο fibonacci (long) -> / metod | fibonacci (long) long -> fibonacci (12) | Η τιμή έκφρασης είναι : 144 | εκχωρήθηκε σε προσωρινή μεταβλητή $ 1 τύπου long -> int [] array = {1,2,3,4,5,6,7,8}; | Προστέθηκε μεταβλητή πίνακας τύπου int [] με αρχική τιμή [I @ 4f4a7090 -> για (long i: array) {System.out.println (fibonacci (i));} 1 1 2 3 5 8 13 21 

Στην ίδια συνεδρία JShell μπορώ να επαναπροσδιορίσω τον ορισμό της μεθόδου Fibonacci και να εκτελέσω τον ίδιο κώδικα. Με αυτόν τον τρόπο μπορείτε να χρησιμοποιήσετε το REPL για γρήγορη εκτέλεση, τροποποίηση και δοκιμή νέων αλγορίθμων.

Λίστα 3. REPL για επαναχρησιμοποίηση

 -> μακρύς fibonacci (μεγάλος αριθμός) {>> return 1; >>} | Τροποποιημένη μέθοδος fibonacci (long) -> for (long i: array) {System.out.println (fibonacci (i)); } 1 1 1 1 1 1 1 

Ορίστε μια τάξη

Το παρακάτω παράδειγμα δείχνει πώς να ορίσετε μια ολόκληρη τάξη στο JShell και, στη συνέχεια, να αναφέρετε αυτήν την κλάση σε μια έκφραση - όλα χωρίς έξοδο από το REPL. Η δυνατότητα δυναμικής δημιουργίας και δοκιμής κώδικα σας ελευθερώνει για να πειραματιστείτε γρήγορα και να επαναλάβετε με νέο κώδικα.

Λίστα 4. Δυναμικός ορισμός κλάσης

 MacOSX: repl tobrien $ bash ./scripts/run.sh | Καλώς ήλθατε στο JShell - Έκδοση 0.710 | Πληκτρολογήστε / βοήθεια για βοήθεια -> Πρόσωπο τάξης {>> δημόσιο όνομα συμβολοσειράς; >> δημόσια εποχή >> δημόσια περιγραφή συμβολοσειράς; >> >> δημόσιο πρόσωπο (Όνομα συμβολοσειράς, int ηλικία, περιγραφή συμβολοσειράς) {>> this.name = name; >> this.age = ηλικία; >> this.description = περιγραφή; >>} >> >> public String toString () {>> επιστροφή αυτού του ονόματος. >>} >>} | Προστέθηκε κατηγορία Person -> Person p1 = new Person ("Tom", 4, "Likes Spiderman"); | Προστέθηκε μεταβλητή p1 του τύπου Person με αρχική τιμή Tom -> / vars | Πρόσωπο p1 = Τομ 

Παρόλο που η ικανότητα δυναμικού ορισμού τάξεων είναι ισχυρή, δεν είναι σαν οι προγραμματιστές να διαφωνούν για να γράφουν μεγάλους, πολλών γραμμών ορισμούς σε ένα διαδραστικό κέλυφος. Αυτό είναι όπου η έννοια του ιστορία και ότι πρόκειται να φορτώσετε και να αποθηκεύσετε την κατάσταση του REPL αρχίζει να γίνεται σημαντικό. Με την /ιστορία εντολή μπορείτε να απαριθμήσετε όλες τις δηλώσεις και εκφράσεις που αξιολογήθηκαν σε REPL.

Λίστα 5. Γνωρίστε το / ιστορικό σας

 -> / class class Person {public String name; δημόσια εποχή δημόσια συμβολοσειρά περιγραφή; δημόσιο πρόσωπο (όνομα συμβολοσειράς, int ηλικία, περιγραφή συμβολοσειράς) {this.name = name; this.age = ηλικία; this.description = περιγραφή; } δημόσια συμβολοσειρά toString () {return this.name; }} Πρόσωπο p1 = νέο άτομο ("Tom", 4, "Likes Spiderman"); Πρόσωπο p2 = νέο άτομο ("Zach", 10, "Good at Math"); / vars p1 p2 / ιστορικό 

Στη συνέχεια, μπορείτε να αποθηκεύσετε το ιστορικό REPL σε ένα αρχείο και να το ονομάσετε έτσι ώστε να μπορεί να φορτωθεί ξανά αργότερα. Ακολουθεί ένα παράδειγμα:

 -> / save output.repl -> / reset | Επαναφορά κατάστασης. -> / vars -> / open output.repl -> / vars | Πρόσωπο p1 = Τομ | Πρόσωπο p2 = Zach 

ο /σώσει Η εντολή αποθηκεύει το ιστορικό REPL σε ένα αρχείο, το /επαναφορά Η εντολή επαναφέρει την κατάσταση του REPL και του /Άνοιξε η εντολή διαβάζεται σε ένα αρχείο και εκτελεί καταστάσεις κατά του REPL. Οι δυνατότητες αποθήκευσης και ανοίγματος σάς επιτρέπουν να ρυθμίσετε πολύπλοκα σενάρια REPL που μπορείτε να χρησιμοποιήσετε για να διαμορφώσετε διαφορετικά σενάρια REPL.

Επεξεργασία ορισμού τάξης εν κινήσει

Το JShell καθιστά επίσης δυνατή την αυτόματη ρύθμιση ενός αρχείου ορισμού εκκίνησης και την αυτόματη φόρτωση ορισμών. Μπορείτε να μεταβείτε στο ιστορικό REPL και να επεξεργαστείτε τις καταχωρημένες πηγές. Για παράδειγμα, αν ήθελα να τροποποιήσω τον ορισμό του Πρόσωπο τάξη από αυτό το παράδειγμα θα μπορούσα να χρησιμοποιήσω το /λίστα και /επεξεργασία εντολές.

Λίστα 6. Τροποποίηση προσώπου

 -> / l 1: άτομο κατηγορίας {δημόσιο όνομα συμβολοσειράς; δημόσια εποχή δημόσια περιγραφή συμβολοσειράς; δημόσιο πρόσωπο (όνομα συμβολοσειράς, int ηλικία, περιγραφή συμβολοσειράς) {this.name = name; this.age = ηλικία; this.description = περιγραφή; } δημόσια συμβολοσειρά toString () {return this.name; }} 2: Πρόσωπο p1 = νέο άτομο ("Tom", 4, "Likes Spiderman"); 3: Πρόσωπο p2 = νέο άτομο ("Zach", 10, "Good at Math"); 4: p1 5: p2 -> / επεξεργασία 1 

Τρέχοντας αυτό /επεξεργασία Η εντολή φορτώνει έναν απλό επεξεργαστή όπου μπορώ να αλλάξω τον ορισμό της κλάσης και να ενημερώσω την τάξη αμέσως.

Ποια είναι η μεγάλη υπόθεση;

Μιλήστε με έναν προγραμματιστή Clojure ή LISP σχετικά με τον τρόπο με τον οποίο αναπτύσσονται καθημερινά και θα δείτε ότι κωδικοποιούν μέσα σε ένα REPL. Δεν γράφουν σενάρια και στη συνέχεια τα εκτελούν όσο περνούν το μεγαλύτερο μέρος του χρόνου ανάπτυξής τους αλλάζοντας αλληλεπιδραστικά τον κώδικα. Εάν έχετε λίγες ώρες για να απομείνετε, ρωτήστε έναν προγραμματιστή Scala ή Clojure για το REPL του. Είναι πώς λειτουργούν.

Η Java είναι διαφορετική γλώσσα από τη Scala ή την Clojure. Οι προγραμματιστές Java δεν ξοδεύουν μέρες επικεντρωμένες σε μεμονωμένες γραμμές LISP που ενδέχεται να περιέχουν ολόκληρες δομές προγράμματος σε μερικές δηλώσεις. Τα περισσότερα προγράμματα Java απαιτούν ρύθμιση ώστε να λειτουργούν σωστά και ενώ οι πρόσφατες αλλαγές στη γλώσσα έχουν μειώσει τον αριθμό γραμμής των συστημάτων που είναι γραμμένα στην Java, εξακολουθούμε να μετράμε την πολυπλοκότητα των συστημάτων μας σε χιλιάδες γραμμές κώδικα. Το απλό Πρόσωπο Το παράδειγμα που αναφέρεται παραπάνω δεν είναι χρήσιμος κώδικας και ο πιο χρήσιμος κώδικας στην Java συνεπάγεται μια πολυπλοκότητα που θα είναι δύσκολο να χωρέσει σε περιβάλλον προγραμματισμού που βασίζεται σε REPL.

Οι προγραμματιστές Scala και Clojure εξασκούν κάτι τέτοιο Προγραμματισμός Clojure Ο συγγραφέας Chas Emerick αποκαλεί "επαναληπτική ανάπτυξη" που δεν εξαρτάται από μια ροή εργασίας που βασίζεται σε αρχεία. Οι προγραμματιστές Java εξαρτώνται από δεκάδες βιβλιοθήκες, σύνθετες ιεραρχίες εξάρτησης και κοντέινερ όπως το Tomcat ή το TomEE. Για αυτόν τον λόγο δεν προβλέπω ότι ο προγραμματισμός με προσανατολισμό REPL θα ξεπεράσει την παραδοσιακή ανάπτυξη Java σε ένα IDE. Αντ 'αυτού, βλέπω το Java REPL να παρέχει μερικά ξεχωριστά οφέλη και ευκαιρίες.

1. Εκμάθηση Java: Επειδή τα προγράμματα Java απαιτούν τόσο μεγάλη ρύθμιση, μπορεί να είναι δύσκολο για τους προγραμματιστές που μαθαίνουν τη γλώσσα να κατανοήσουν γρήγορα τη σύνταξη. Το Java 9's REPL θα γίνει ο πρωταρχικός τρόπος με τον οποίο οι νέοι προγραμματιστές θα αντιμετωπίσουν τη βασική σύνταξη.

2. Πειραματισμός με νέες βιβλιοθήκες: Η Java διαθέτει εκατοντάδες χρήσιμες βιβλιοθήκες ανοιχτού κώδικα για τα πάντα, από χειρισμό ημερομηνίας και ώρας έως βιβλιοθήκες μαθηματικών. Χωρίς REPL, κάθε φορά που ένας προγραμματιστής θέλει να κατανοήσει μια νέα βιβλιοθήκη, αναπόφευκτα δημιουργούν μερικά μαθήματα με το συνηθισμένο "δημόσιο στατικό κενό"Τελετή. Με ένα REPL μπορείτε απλώς να το ενεργοποιήσετε και να παίξετε χωρίς αυτό το overhead.

3. Γρήγορο πρωτότυπο: Αυτό είναι πιο κοντά στον τρόπο με τον οποίο οι περισσότεροι προγραμματιστές Clojure και Scala λειτουργούν επαναληπτικά, αλλά εάν εργάζεστε σε ένα εστιασμένο πρόβλημα, ένα REPL καθιστά εύκολη την ταχεία επανάληψη αλλαγών σε τάξεις και αλγόριθμους. Με ένα REPL δεν θα χρειαστεί να περιμένετε να ολοκληρωθεί μια κατασκευή. μπορείτε να τροποποιήσετε γρήγορα τον ορισμό μιας τάξης, να επαναφέρετε το REPL σας και να το δοκιμάσετε ξανά.

4. Ενσωμάτωση με συστήματα κατασκευής: Το Gradle παρέχει μια διαδραστική λειτουργία "shell" και η κοινότητα Maven έχει αποστείλει παρόμοια εργαλεία στο παρελθόν. Οι προγραμματιστές που θέλουν να μειώσουν την πολυπλοκότητα κατασκευής θα μπορούσαν να εξερευνήσουν χρησιμοποιώντας ένα REPL ως εργαλείο για την ενορχήστρωση άλλων συστημάτων.

Ο τελικός μου 2γ

Βλέπω το Java REPL ως κάτι που θα αρχίσει να επηρεάζει την καθημερινή ανάπτυξη τα επόμενα χρόνια, για όσους κάνουν αναβάθμιση σε Java 9. Πιστεύω επίσης ότι η κοινότητα Java θα χρειαστεί χρόνο για να προσαρμοστεί πλήρως στο νέο στυλ ανάπτυξης και κατανοήστε τόσο τις προκλήσεις όσο και τις ευκαιρίες που παρέχει μια REPL. Δεν περιμένω ότι οι περισσότεροι προγραμματιστές Java θα μεταβούν σε ανάπτυξη με προσανατολισμό το REPL, όπως έχουν οι ξάδελφοι προγραμματισμού Clojure, αλλά πιστεύω ότι θα δούμε ότι το REPL επηρεάζει τον τρόπο με τον οποίο οι νέοι προγραμματιστές μαθαίνουν την Java. Καθώς οι νέοι προγραμματιστές Java συναντούν την Java για πρώτη φορά μέσα σε ένα REPL, δεν υπάρχει αμφιβολία ότι θα αρχίσει να επηρεάζει τον τρόπο δημιουργίας και πρωτοτύπων συστημάτων που βασίζονται σε Java.

Αυτή η ιστορία, "Τι σημαίνει REPL για Java" δημοσιεύθηκε αρχικά από το JavaWorld.