কখনও কখনও কিছু স্টেট একাধিক ওয়ার্ডের মধ্যে শেয়ার করা দরকার, প্রতিবার সেটিকে তাদের স্ট্যাক ইফেক্টের মধ্য দিয়ে পার করানো ছাড়াই। 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 |
integer |
registered-to |
string |
open-garden ডিফাইন করুন যাতে ডাইনামিক ভ্যারিয়েবলগুলো ইনিশিয়ালাইজ হয়: registrations-এর জন্য একটি খালি ভেক্টর, আর next-id-এর জন্য 1। এরপর 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টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।