Néha egy állapotot több szó között kell megosztani anélkül, hogy minden alkalommal átfűznéd a veremhatásaikon. A Factor dinamikus változói, amelyeket a SYMBOL: segítségével deklarálunk, minden szó számára hozzáférést adnak egy névtérben tárolt értékhez.
SYMBOL: és SYMBOLS:
A SYMBOL: name egyetlen változót deklarál. A SYMBOLS: a b c ; egyszerre többet:
USING: namespaces ;
SYMBOLS: counter total ;
A set-global és a get-global (a namespaces szótárban) a globális névtéren működik:
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
Modulszintű állapothoz a -global változatokra van szükséged.
with-variable segítségévelEgy dinamikus változó egy második, scope-hoz kötött változatot is támogat. A set / get / change (a -global utótag nélkül) az aktuális dinamikus scope-ot olvassa és írja, a with-variable pedig (a namespaces szótárban) friss scope-ot hoz létre, amely egy quotation futásáig tart:
with-variable ( value variable quot -- )
set ( value variable -- )
get ( variable -- value )
change ( variable quot: ( old -- new ) -- )
A változó a value értékhez van kötve, amíg a quot fut; amint visszatér, a kötés eltűnik. Így egy külső hívó „be tud injektálni” egy értéket, amelyet a belső kód el tud olvasni anélkül, hogy minden veremszignatúrán át kellene fűzni.
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)
Ez a feladat végig a globális változatot használja, de a párhuzamos set/get/change család felismerése hasznos, amikor mások kódját olvasod.
Mivel a dinamikus változók referenciát tárolnak, egy módosítható gyűjteményt is tarthatsz bennük, és a helyén frissítheted:
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" }
A V{ … } egy vektorliterál. A V{ } literált mindig clone-ozd, mielőtt eltárolod: a literálok megosztottak a hívások között.
find: az első egyezésA find (a sequences szótárban) visszaadja az első olyan elemet, amelyre egy predikátum igazat ad, valamint annak indexét:
find ( seq quot -- index elt/f )
Ha semmi sem egyezik, mindkét érték f. Az index eldobása a nip-pel, majd az unless* használata a szokásos „alapérték, ha hiányzik” kombináció.
reject: a találatok elvetéseA reject (szintén a sequences szótárban) a filter ellentéte: azokat az elemeket adja vissza, amelyekre a predikátum nem igaz.
A közösségi egyesületed arra kér, hogy kezeld a kert parcelláinak regisztrációit. Az állapot két dinamikus változóban él:
registrations: a jelenleg egy személyhez rendelt plot tuple-ök vektora.next-id: a következő regisztrációhoz használandó egész szám.A plot tuple két mezővel rendelkezik:
| mező | típus |
|---|---|
id |
egész szám |
registered-to |
string |
Definiáld az open-garden függvényt, amely inicializálja a dinamikus változókat: a registrations legyen egy üres vektor, a next-id pedig 1. Ezután definiáld a list-registrations függvényt, amely visszaadja a parcellák aktuális vektorát.
open-garden
list-registrations .
! => V{ }
Definiáld a register függvényt, amely levesz egy nevet a veremről, létrehoz egy új plot-ot a következő szabad azonosítóval, hozzáfűzi a registrations vektorhoz, eggyel növeli a next-id értékét, és visszaadja az új parcellát.
open-garden
"Emma Balan" register .
! => T{ plot { id 1 } { registered-to "Emma Balan" } }
list-registrations .
! => V{ T{ plot { id 1 } { registered-to "Emma Balan" } } }
A parcella-azonosítóknak egyedinek kell lenniük, és egy felszabadítás után is növekedniük kell. A next-id soha ne használjon újra egy értéket.
Definiáld a release függvényt, amely átvesz egy azonosítót, és eltávolítja a hozzá tartozó bejegyzést a registrations vektorból. Az ismeretlen azonosító felszabadítása nem változtat semmin.
open-garden
"Emma" register drop
1 release
list-registrations .
! => V{ }
Definiáld a get-registration függvényt, amely átvesz egy azonosítót, és visszaadja a hozzá tartozó parcellát, vagy a not-found szimbólumot, ha egyetlen parcella sem rendelkezik ezzel az azonosítóval.
open-garden
"Emma" register drop
1 get-registration .
! => T{ plot { id 1 } { registered-to "Emma" } }
7 get-registration .
! => not-found
Definiáld a find-by-name függvényt, amely átvesz egy nevet, és visszaadja az adott személyhez jelenleg regisztrált összes parcella vektorát.
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" } } }
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Factor nyelvet 47 fogalom163 feladat segítségével, valódi emberi mentorálással, mindez ingyen.