סקלרים קשורים#

סקלר קשור הוא ממשק ה־tie הקטן ביותר והמקום הטוב ביותר ללמוד את הצורה של כל האחרים. אתם מגדירים בנאי ושתי מתודות accessor; מאותו רגע, כל קריאה של המשתנה קוראת לאחת מהן וכל כתיבה קוראת לאחרת.

המחלקה זקוקה לארבע מתודות, שתיים מהן אופציונליות:

  • TIESCALAR - הבנאי, נקרא פעם אחת על ידי tie.

  • FETCH - נקראת בכל קריאה של המשתנה.

  • STORE - נקראת בכל כתיבה אל המשתנה.

  • DESTROY - נקראת כאשר המשתנה הקשור נעלם (אופציונלי).

רשימת החתימות המלאה נמצאת בעמוד העזר tie. פרק זה מראה מה כל מתודה עושה באמצעות בניית אחת כזו.

מחלקה שלמה#

מונה שמגביל כתיבות כך שהערך לעולם אינו יורד מתחת לאפס:

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. ירשו ממנו ועקפו רק את הוו שאתם רוצים לשנות:

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 - המובנה, עם תפריט המתודות המלא לכל סוג

  • tied - שחזרו את העצם שתומך במשתנה כדי לקרוא עליו מתודות ספציפיות למחלקה

  • untie - פירוק הקישור

  • האשים קשורים - השלב הבא למעלה: בנאי בתוספת פרוטוקול איטרציה

  • Tie::Scalar - מודול מחלקת הבסיס; Tie::StdScalar הוא הגרסה הקונקרטית שבדרך כלל תרצו