مسیرها
/
Factor
Factor
/
تمرین‌ها
/
گردهمایی باغ
گردهمایی باغ

گردهمایی باغ

تمرین یادگیری

مقدمه

گاهی لازم است تکه‌ای از وضعیت میان چندین «واژه» به اشتراک گذاشته شود، بدون اینکه هر بار آن را از میان اثرهای پشته‌ی آن‌ها عبور دهید. متغیرهای پویای 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

برای وضعیت سطح ماژول، گونه‌های -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 ) -- )

تا زمانی که quot اجرا می‌شود، متغیر به value متصل است؛ به‌محض اینکه برگردد، اتصال از میان می‌رود. این کار به یک فراخواننده‌ی بیرونی اجازه می‌دهد مقداری را «تزریق» کند که کد درونی بتواند آن را بخواند، بدون اینکه آن را از میان هر امضای پشته عبور دهد.

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{ … } یک بردار لیترال است. همیشه یک لیترال V{ } را پیش از ذخیره‌کردنش clone کنید: لیترال‌ها میان فراخوانی‌ها به اشتراک گذاشته می‌شوند.

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 را تعریف کنید تا بردار کنونی قطعه‌ها را برگرداند.

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

2. یک قطعه ثبت کنید

register را تعریف کنید تا یک اسم را از پشته بردارد، یک plot تازه با شناسه‌ی در دسترس بعدی بسازد، آن را به بردار registrations بیفزاید، next-id را یک واحد افزایش دهد و قطعه‌ی جدید را برگرداند.

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

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

شناسه‌های قطعه باید یکتا باشند و حتی بعد از آزادسازی هم افزایش پیدا کنند. next-id هرگز نباید مقداری را دوباره استفاده کند.

3. یک قطعه را آزاد کنید

release را تعریف کنید تا یک شناسه بگیرد و عنصر متناظر را از registrations حذف کند. آزاد کردن یک شناسه‌ی ناشناخته هیچ کاری انجام نمی‌دهد.

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

4. یک قطعه‌ی ثبت‌شده را بگیرید

get-registration را تعریف کنید تا یک شناسه بگیرد و قطعه‌ی متناظر را برگرداند، یا اگر هیچ قطعه‌ای آن شناسه را نداشت، نماد not-found را برگرداند.

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

7 get-registration .
! => not-found

5. قطعه‌ها را بر اساس اسم پیدا کنید

find-by-name را تعریف کنید تا یک اسم بگیرد و برداری از همه‌ی قطعه‌هایی را برگرداند که در حال حاضر به آن شخص ثبت شده‌اند.

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 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.