أحيانًا يحتاج جزء من الحالة إلى أن يكون مشتركًا بين عدة كلمات
دون تمريره عبر آثار المكدس الخاصة بها في كل مرة. المتغيرات
الديناميكية في 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 ) -- )
يُربط المتغير بـvalue أثناء تشغيل quot؛ وبمجرد انتهائه،
يختفي الارتباط. يتيح هذا للمستدعي الخارجي "حقن" قيمة يمكن
للكود الداخلي قراءتها دون تمريرها عبر كل توقيع مكدس.
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{ … } هو متجه حرفي. استخدم clone دائمًا على V{ } الحرفي
قبل تخزينه: فالقيم الحرفية مشتركة بين الاستدعاءات.
find: أول تطابقfind (في sequences) تُرجع أول عنصر يكون
محموله صحيحًا، بالإضافة إلى فهرسه:
find ( seq quot -- index elt/f )
إذا لم يطابق شيء، فكلتا القيمتين f. إسقاط الفهرس باستخدام
nip واستخدام unless* هو المزيج القياسي "الافتراضي عند
الغياب".
reject: إسقاط المطابقاتreject (أيضًا في sequences) هي عكس filter:
تُرجع العناصر التي تفشل في اختبار المحمول.
تطلب منك جمعية الحي إدارة تسجيلات قطع الأرض في الحديقة. تُخزَّن الحالة في متغيرين ديناميكيين:
registrations: متجه من صفوف plot المخصصة حاليًا لشخص.next-id: العدد الصحيح الذي سيُستخدم للتسجيل التالي.يحتوي صف plot على خانتين:
| الخانة | النوع |
|---|---|
id |
عدد صحيح |
registered-to |
سلسلة نصية |
عرّف open-garden لتهيئة المتغيرين الديناميكيين: متجه فارغ لـ registrations، و1 لـ next-id. ثم عرّف list-registrations لتُرجع متجه القطع الحالي.
open-garden
list-registrations .
! => V{ }
عرّف 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 استخدام أي قيمة أبدًا.
عرّف release لتأخذ معرّفًا وتحذف المدخل المطابق من registrations. تحرير معرّف غير معروف عملية لا تفعل شيئًا.
open-garden
"Emma" register drop
1 release
list-registrations .
! => V{ }
عرّف get-registration لتأخذ معرّفًا وتُرجع القطعة المطابقة، أو الرمز not-found إذا لم تكن هناك قطعة بهذا المعرّف.
open-garden
"Emma" register drop
1 get-registration .
! => T{ plot { id 1 } { registered-to "Emma" } }
7 get-registration .
! => not-found
عرّف 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" } } }
سجّل في Exercism لتتعلّم وتتقن Factor عبر 47 مفهومًا163 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.