# סקלרים קשורים סקלר קשור הוא ממשק ה־tie הקטן ביותר והמקום הטוב ביותר ללמוד את הצורה של כל האחרים. אתם מגדירים בנאי ושתי מתודות accessor; מאותו רגע, כל קריאה של המשתנה קוראת לאחת מהן וכל כתיבה קוראת לאחרת. המחלקה זקוקה לארבע מתודות, שתיים מהן אופציונליות: - `TIESCALAR` - הבנאי, נקרא פעם אחת על ידי [`tie`](../../p5/core/perlfunc/tie.md). - `FETCH` - נקראת בכל קריאה של המשתנה. - `STORE` - נקראת בכל כתיבה אל המשתנה. - `DESTROY` - נקראת כאשר המשתנה הקשור נעלם (אופציונלי). רשימת החתימות המלאה נמצאת בעמוד העזר [`tie`](../../p5/core/perlfunc/tie.md). פרק זה מראה מה כל מתודה עושה באמצעות בניית אחת כזו. ## מחלקה שלמה מונה שמגביל כתיבות כך שהערך לעולם אינו יורד מתחת לאפס: ```perl use v5.36; package Counter { sub TIESCALAR { my ($class, $start) = @_; my $n = $start // 0; return bless \$n, $class; } sub FETCH { my $self = shift; return $$self } sub STORE { my ($self, $value) = @_; $$self = $value < 0 ? 0 : $value; # never go below zero } sub DESTROY { } } tie my $hits, 'Counter', 10; say $hits; # 10 $hits = 25; say $hits; # 25 $hits = -7; say $hits; # 0 ``` העצם שמאחורי הסקלר יכול להיות כל דבר שעבר blessed - כאן הפניה למספר רגיל. ה־`LIST` שאחרי שם המחלקה בקריאת `tie` (`10`) מועבר ישירות אל `TIESCALAR`. ## חוזה המתודות `TIESCALAR classname, LIST` : הבנאי. הוא מקבל את שם המחלקה ואת כל הארגומנטים הנוספים שהועברו אל `tie`. הוא חייב להחזיר הפניה שעברה blessed; אותה הפניה הופכת לעצם הקשור ולערך ההחזרה של קריאת `tie`. קיצור דרך נפוץ הוא הפניית סקלר שעברה blessed ומחזיקה את הערך, כמו למעלה, אבל הפניית האש שעברה blessed תקפה בדיוק באותה מידה כאשר המחלקה זקוקה ליותר מצב. `FETCH this` : נקראת בכל פעם שהמשתנה נקרא. היא מקבלת רק את העצם. כל מה שהיא מחזירה הוא מה שהקורא רואה. `FETCH` הוא המקום שבו סקלר מחושב מצדיק את עצמו: הוא יכול לחשב מחדש, לחפש משהו, או לרשום את הגישה ולהחזיר ערך מאוחסן. `STORE this, value` : נקראת בכל פעם שמתבצעת השמה למשתנה. היא מקבלת את העצם ואת הערך החדש היחיד. ערך ההחזרה שלה נזנח - ערך ביטוי ההשמה מגיע מ־`FETCH` עוקב, לא מ־`STORE`. כאן שוכנים האימות, ההגבלה, או הכתיבה־מבעד אל מאגר תומך. `DESTROY this` : נקראת כאשר המשתנה הקשור מושמד (יציאה מתחום, או נפילת ההפניה האחרונה). הגדירו אותה רק כאשר המחלקה מחזיקה משאב שדורש שחרור - מטפל פתוח, נעילה. למונה אין דבר לנקות, ולכן ה־`DESTROY` שלו ריק או מושמט לחלוטין. ## תזמון הקריאה - קריאה בכל הקשר קוראת ל־`FETCH`. `say $hits`, `$x = $hits + 1`, ו־`"$hits"` כל אחד מהם מפעיל `FETCH` אחד. - השמה קוראת ל־`STORE` עם הערך שמימין. `$hits = 25` קורא ל־`STORE($obj, 25)`. - השמה מורכבת קוראת ואז כותבת: `$hits += 5` קורא ל־`FETCH`, מוסיף 5, ואז `STORE`. כך גם `$hits++`. - הערך של ביטוי השמה מגיע מ־`FETCH`, לא מערך ההחזרה של `STORE`. לאחר `my $r = ($hits = -7)`, `$r` הוא `0` מכיוון שההגבלה רצה ב־`STORE` וערך הביטוי נשלף בחזרה. ## מחלקה מינימלית ברת־קיימא הסקלר הקשור השמיש הקטן ביותר מגדיר בדיוק את `TIESCALAR`, `FETCH`, ו־`STORE`. השמיטו את `DESTROY` אלא אם אתם מקצים משהו. מחלקה עם `TIESCALAR` ו־`FETCH` בלבד מייצרת סקלר לקריאה בלבד: היא נקשרת כראוי, אבל ההשמה הראשונה מתה עם `Can't locate object method "STORE"`. ## הדרך הקלה: ירושה מ־`Tie::StdScalar` `Tie::StdScalar` (מסופק בתוך `Tie::Scalar`) מממש את `TIESCALAR`, `FETCH`, `STORE`, ו־`DESTROY` מעל הפניית סקלר שעברה blessed. ירשו ממנו ועקפו רק את הוו שאתם רוצים לשנות: ```perl package Uppercase { use Tie::Scalar; our @ISA = ('Tie::StdScalar'); sub STORE { my ($self, $v) = @_; $$self = uc $v } } tie my $shout, 'Uppercase'; $shout = 'hello'; say $shout; # HELLO ``` `STORE` ממיר לאותיות רישיות בדרך פנימה; `FETCH` והבנאי מגיעים ממחלקת הבסיס ללא שינוי. `Tie::Scalar` עצמו הוא הבסיס ה *מופשט* - הוא מגדיר `FETCH` ו־`STORE` שעושים croak, ולכן יצירת תת־מחלקה ממנו ישירות פירושה אספקת `TIESCALAR` משלכם. פנו אל `Tie::StdScalar` כאשר אתם רוצים בנאי פועל בחינם; פנו אל `Tie::Scalar` רק כאשר אתם מתכוונים לכתוב כל מתודה בכל מקרה ורוצים שהממשק יתועד באמצעות ירושה. ## ראו גם - [`tie`](../../p5/core/perlfunc/tie.md) - המובנה, עם תפריט המתודות המלא לכל סוג - [`tied`](../../p5/core/perlfunc/tied.md) - שחזרו את העצם שתומך במשתנה כדי לקרוא עליו מתודות ספציפיות למחלקה - [`untie`](../../p5/core/perlfunc/untie.md) - פירוק הקישור - [האשים קשורים](hashes.md) - השלב הבא למעלה: בנאי בתוספת פרוטוקול איטרציה - `Tie::Scalar` - מודול מחלקת הבסיס; `Tie::StdScalar` הוא הגרסה הקונקרטית שבדרך כלל תרצו