תת־שגרות#
תת־שגרה היא בלוק קוד בעל שם (או אנונימי) המקבל רשימת ארגומנטים, רץ בתחום לקסיקלי חדש, ומחזיר רשימת ערכים. תת־שגרות הן יחידת השימוש החוזר ב־Perl, יחידת השיגור עבור קוד מונחה־עצמים, ו - באמצעות closures
יחידת הכימוס בעל המצב. כמעט כל דבר אחר בשפה בנוי מעליהן.
PetaPerl מממש את מודל תת־השגרות המלא של Perl 5.42: מוסכמת הקריאה הקלאסית המבוססת על @_, חתימות מודרניות, מנגנון ה־prototype השולט בניתוח אתר־הקריאה, תיחום לקסיקלי ותיחום חבילה (my, our, local, state), closures, מערכת המאפיינים (:lvalue, :method, :prototype(...)), רקורסיה עם קריאות זנב goto &sub, והבלוקים המיוחדים של זמן־הידור וזמן־ריצה (BEGIN, END, INIT, CHECK, UNITCHECK).
מסמך עזר זה מחולק לעמוד אחד לכל נושא. כלל ה־aliasing של @_ שוכן עם הארגומנטים, מלכודת ה־closure־מעל־משתנה־הלולאה שוכנת עם התיחום, והשפעות ה־prototype ברמת המנתח שוכנות עם ה־prototype - כך שכל עמוד ניתן לקריאה ולחזרה אליו ללא הקשר רחב.
בחירת נושא#
הצהרה -
sub NAME { ... }, תת־שגרות אנונימיות, הצהרות מקדימות, הפניות לקוד, הסיגיל&ומה הצהרה מוקדמת מעניקה לך.ארגומנטים ו־
@_- כלל ה־aliasing, ניב הפירוק, מוסכמות ארגומנטים בעלי שם, ברירות המחדל שלshift, השימוש הלגיטימי ב־aliasing שלchomp(@lines), ומלכודת$_[0] = ....ערכי החזרה -
returnמפורש, החזרת הביטוי האחרון באופן משתמע, השטחת רשימה בהחזרה, קיצורי דרך בהקשר void, וההבדל ביןreturn;לביןreturn undef;.תיחום:
my,our,local,state- אורך חיי ה־pad, closures, ההפתעה של closure־מעל־משתנה־הלולאה, מתיlocalהוא הכלי הנכון, ומהstateבאמת אומר.Prototypes - מה הם עושים (ניתוח אתר־הקריאה), מה הם לא עושים (בדיקות זמן־ריצה), ההבדל בין
(\@)לבין(@), ה־prototype של()לקיפול־קבועים, ומדוע רוב הקוד המודרני לא צריך לפנות אליהם.חתימות - התחביר המודרני מ־5.20+ היציב ב־5.36, עם פרמטרים מיקומיים, אופציונליים, ו־slurpy; ברירות מחדל; פרמטרים בעלי שם באמצעות hash מסוג slurpy; וכיצד חתימות מתקשרות עם (ואינן מחליפות את) ה־prototypes.
רקורסיה - מגבלת עומק, רקורסיה הדדית,
goto &fnעבור קריאות זנב,__SUB__עבור הפניה־עצמית אנונימית, טרמפולינות.תת־שגרות lvalue והקשר - הסמנטיקה של
:lvalue,wantarray, המתג התלת־כיווני void־סקלר־רשימה, ותבנית הסטנדרט של ”החזרה מוקדמת בהקשר void“.מאפיינים -
:method,:lvalue,:prototype(...),:const, מאפיינים של צד שלישי, וכיצד מתחברים ארבעת השלבים הקשורים למאפיינים (ניתוח, רישום, אחסון, שאילתה).Phasers - הבלוקים
BEGIN,UNITCHECK,CHECK,INITו-END: מתי כל אחד מהם נורה ביחס לגבול ההידור/הריצה, סדר ה-FIFO/LIFO שלהם,$?ו-${^GLOBAL_PHASE}בתוךEND, והבלוקdefer.
הגדרת תת־שגרה לעומת קריאה לתת־שגרה#
שני החצאים של מערכת תת־השגרות הם בעיקרם אורתוגונליים:
הגדרה היא הצהרה בתוספת גוף. ההצהרה קובעת את השם (או הופכת את תת־השגרה לאנונימית), את ה־prototype או החתימה האופציונליים, ואת המאפיינים האופציונליים. הגוף הוא בלוק של פקודות עם ה־pad משלו.
קריאה הופכת רשימת ביטויים ל־
@_של ה־pad החדש (או למשתני החתימה), מריצה את הגוף, ואוספת את כל מה שהגוף החזיר בהקשר של הקורא.
כמעט כל שאלה ”עדינה“ על תת־שגרות היא שאלה על צד אחד או על האחר. Prototypes משפיעים על קריאות בלבד, לא על הגדרות; חתימות משפיעות על מה שהגוף רואה, לא על האופן שבו הקורא כותב את הקריאה; מאפיינים משפיעים על האופן שבו זמן־הריצה מתייחס לתת־השגרה המוגדרת.
החלוקה הקלאסית לעומת המודרנית#
Perl נושאת שני מנגנונים מקבילים להעברת ארגומנטים:
# Classic: @_ aliasing, manual unpacking
sub add {
my ($a, $b) = @_;
return $a + $b;
}
# Modern: signatures, named lexicals, arity checking
use feature 'signatures';
sub add ($a, $b) {
return $a + $b;
}
שניהם נתמכים במלואם. חתימות אינן תחליף ל־@_; הן כניסה נוספת ודקלרטיבית יותר לאותה מוסכמת קריאה. בתוך תת־שגרה המשתמשת בחתימה, @_ עדיין מאוכלס (זוהי התנהגות מוגדרת־מימוש ולא מומלץ להסתמך עליה, אך זה המצב ב־5.42).
החלוקה בין הקלאסי למודרני היא פרט ההתמצאות השימושי ביותר בעת קריאת Perl של אנשים אחרים. רוב הקוד הישן משתמש בצורה הקלאסית; רוב הקוד החדש משתמש בחתימות; שניהם יעמדו מולך בכל בסיס־קוד לא־טריוויאלי.
ראו גם#
perlop- אופרטורים המתקשרים עם תת־שגרות:->לשיגור מתודות והפעלת הפניות־קוד,,(והפסיק השמן) לבניית ארגומנטים בעלי שם,=להשמת הרשימה המשמשת בניבmy (...) = @_.perlvar- משתנים מיוחדים שתת־שגרה תקרא או תכתוב:@_,$_,$@,$AUTOLOAD.perlfunc- הפעלים של מערכת תת־השגרות:sub,return,caller,wantarray,prototype,goto,my,our,state,local.תכנות מונחה־עצמים - תת־שגרות כמתודות, תפקיד
bless, שיגור באמצעות@ISA, התחביר המודרניuse experimental 'class'.