Kurzusok
/
Factor
Factor
/
Feladatok
/
Kerti gyűjtés
Kerti gyűjtés

Kerti gyűjtés

Tanulófeladat

Bevezetés

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 ;

Beállítás és lekérés

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.

Scope-hoz kötött kötések a with-variable segítségével

Egy 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.

Módosítható vektorok

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és

A 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ése

A reject (szintén a sequences szótárban) a filter ellentéte: azokat az elemeket adja vissza, amelyekre a predikátum nem igaz.

Utasítások

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

1. Nyisd meg a kertet, és listázd a regisztrációit

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{ }

2. Regisztrálj egy parcellát

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.

3. Szabadíts fel egy parcellát

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{ }

4. Kérj le egy regisztrált parcellát

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

5. Keress parcellákat név alapján

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" } } }
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Factor Exercism

Készen állsz elkezdeni a(z) Kerti gyűjtés feladatot?

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.