Διαδρομές
/
Factor
Factor
/
Ασκήσεις
/
Συνάντηση στον κήπο
Συνάντηση στον κήπο

Συνάντηση στον κήπο

Άσκηση εκμάθησης

Εισαγωγή

Μερικές φορές ένα κομμάτι κατάστασης πρέπει να μοιράζεται ανάμεσα σε πολλές λέξεις, χωρίς να το περνάς κάθε φορά μέσα από τα stack effects τους. Οι δυναμικές μεταβλητές της Factor, που δηλώνονται με SYMBOL:, δίνουν σε κάθε λέξη πρόσβαση σε μια τιμή που είναι αποθηκευμένη σε έναν χώρο ονομάτων.

SYMBOL: και SYMBOLS:

Το SYMBOL: name δηλώνει μία μεταβλητή. Το SYMBOLS: a b c ; δηλώνει πολλές μαζί:

USING: namespaces ;

SYMBOLS: counter total ;

Ορισμός και ανάγνωση

Τα set-global και get-global (στο namespaces) λειτουργούν στον καθολικό χώρο ονομάτων:

set-global    ( value variable -- )
get-global    ( variable -- value )
change-global ( variable quot: ( old -- new ) -- )
0 counter set-global
counter get-global .         ! => 0
counter [ 10 + ] change-global
counter get-global .         ! => 10

Για κατάσταση σε επίπεδο module, οι εκδοχές -global είναι αυτές που χρειάζεσαι.

Δεσμεύσεις με εμβέλεια με το with-variable

Μια δυναμική μεταβλητή υποστηρίζει επίσης μια δεύτερη εκδοχή, με εμβέλεια. Τα set / get / change (χωρίς την κατάληξη -global) διαβάζουν και γράφουν την τρέχουσα δυναμική εμβέλεια, και το with-variable (στο namespaces) δημιουργεί μια νέα εμβέλεια όσο διαρκεί μια παράθεση:

with-variable ( value variable quot -- )
set           ( value variable -- )
get           ( variable -- value )
change        ( variable quot: ( old -- new ) -- )

Η μεταβλητή είναι δεσμευμένη στην value όσο εκτελείται η quot; μόλις αυτή επιστρέψει, η δέσμευση εξαφανίζεται. Αυτό επιτρέπει σε έναν εξωτερικό καλούντα να "εισάγει" μια τιμή που ο εσωτερικός κώδικας μπορεί να διαβάσει, χωρίς να την περνά μέσα από κάθε stack signature.

SYMBOL: greeting

"Hello" greeting [
    greeting get .                ! => "Hello"
    "Howdy" greeting set
    greeting get .                ! => "Howdy"
    greeting [ "!" append ] change
    greeting get .                ! => "Howdy!"
] with-variable

greeting get-global .    ! => f   (the scoped binding is gone)

Αυτή η άσκηση χρησιμοποιεί την καθολική εκδοχή σε όλη τη διάρκεια, αλλά το να αναγνωρίζεις την παράλληλη οικογένεια set/get/change είναι χρήσιμο όταν διαβάζεις κώδικα άλλων.

Μεταβλητά διανύσματα

Επειδή οι δυναμικές μεταβλητές κρατούν μια αναφορά, μπορείς να κρατάς μια μεταβλητή συλλογή μέσα σε μία από αυτές και να την ενημερώνεις επιτόπου:

SYMBOL: history

V{ } clone history set-global
"first event" history get-global push
"second event" history get-global push
history get-global .
! => V{ "first event" "second event" }

Το V{ … } είναι ένα literal διάνυσμα. Πάντα να κάνεις clone σε ένα literal V{ } πριν το αποθηκεύσεις: τα literals μοιράζονται μεταξύ των κλήσεων.

find, το πρώτο ταίριασμα

Το find (στο sequences) επιστρέφει το πρώτο στοιχείο για το οποίο ένα κατηγόρημα είναι αληθές, μαζί με τη θέση του:

find ( seq quot -- index elt/f )

Αν δεν ταιριάζει τίποτα, και οι δύο τιμές είναι f. Το να πετάξεις τη θέση με το nip και να χρησιμοποιήσεις το unless* είναι ο καθιερωμένος συνδυασμός για "προεπιλογή αν λείπει".

reject, πέταξε τα ταιριάσματα

Το reject (επίσης στο sequences) είναι το αντίθετο του filter: επιστρέφει τα στοιχεία που αποτυγχάνουν στο κατηγόρημα.

Οδηγίες

Ο σύλλογος της γειτονιάς σου σου ζητά να διαχειριστείς τις εγγραφές στα παρτέρια του κήπου. Η κατάσταση αποθηκεύεται σε δύο δυναμικές μεταβλητές:

  • registrations — ένα διάνυσμα από πλειάδες plot που είναι αυτή τη στιγμή ανατεθειμένες σε κάποιο άτομο.
  • next-id — ο ακέραιος που θα χρησιμοποιηθεί για την επόμενη εγγραφή.

Η πλειάδα plot έχει δύο θέσεις:

θέση τύπος
id ακέραιος
registered-to συμβολοσειρά

1. Άνοιξε τον κήπο και εμφάνισε τις εγγραφές του

Όρισε τη συνάρτηση open-garden ώστε να αρχικοποιεί τις δυναμικές μεταβλητές: ένα κενό διάνυσμα για το registrations και 1 για το next-id. Στη συνέχεια, όρισε τη συνάρτηση list-registrations ώστε να επιστρέφει το τρέχον διάνυσμα με τις πλειάδες plot.

open-garden
list-registrations .
! => V{ }

2. Καταχώρισε ένα παρτέρι

Όρισε τη συνάρτηση register ώστε να παίρνει ένα όνομα από τη στοίβα, να δημιουργεί μια νέα πλειάδα plot με το επόμενο διαθέσιμο id, να την προσθέτει στο διάνυσμα registrations, να αυξάνει το next-id κατά ένα και να επιστρέφει τη νέα πλειάδα plot.

open-garden
"Emma Balan" register .
! => T{ plot { id 1 } { registered-to "Emma Balan" } }

list-registrations .
! => V{ T{ plot { id 1 } { registered-to "Emma Balan" } } }

Τα id των παρτεριών πρέπει να είναι μοναδικά και να αυξάνονται ακόμη και μετά από μια ελευθέρωση. Το next-id δεν πρέπει ποτέ να ξαναχρησιμοποιεί μια τιμή.

3. Ελευθέρωσε ένα παρτέρι

Όρισε τη συνάρτηση release ώστε να παίρνει ένα id και να αφαιρεί την αντίστοιχη καταχώριση από το registrations. Η ελευθέρωση ενός άγνωστου id δεν κάνει τίποτα.

open-garden
"Emma" register drop
1 release
list-registrations .
! => V{ }

4. Πάρε ένα καταχωρισμένο παρτέρι

Όρισε τη συνάρτηση get-registration ώστε να παίρνει ένα id και να επιστρέφει την αντίστοιχη πλειάδα plot ή το σύμβολο not-found αν κανένα παρτέρι δεν έχει αυτό το id.

open-garden
"Emma" register drop
1 get-registration .
! => T{ plot { id 1 } { registered-to "Emma" } }

7 get-registration .
! => not-found

5. Βρες παρτέρια με βάση το όνομα

Όρισε τη συνάρτηση find-by-name ώστε να παίρνει ένα όνομα και να επιστρέφει ένα διάνυσμα με όλες τις πλειάδες plot που είναι αυτή τη στιγμή καταχωρισμένες σε αυτό το άτομο.

open-garden
"Emma" register drop
"Bob" register drop
"Emma" register drop
"Emma" find-by-name .
! => V{ T{ plot { id 1 } { registered-to "Emma" } }
        T{ plot { id 3 } { registered-to "Emma" } } }
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Factor Exercism

Έτοιμος να ξεκινήσεις την άσκηση Συνάντηση στον κήπο;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Factor με 47 έννοιες163 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.