התבוננות פנימית במפרש#
משתנים החושפים את מפרש ה־Perl הרץ ואת התצורה שלו. רוב הקוד לעולם אינו נוגע בהם; המקרים שבהם הם חשובים הם בדיקות גרסה, לוגיקה מותנית במערכת ההפעלה, הוּוי profiler, ועריכה במקום.
משתנה | מחזיק |
|---|---|
| גרסת Perl כמחרוזת מספרית ( |
| גרסת Perl כעצם |
| שם מערכת ההפעלה ( |
| נתיב לקובץ ההפעלה הרץ של Perl/PetaPerl |
| basetime של התהליך (שניות Unix epoch) |
| מתג ראשי של אזהרות (בוליאני) |
| סיומת עריכה במקום (נקבעת על ידי |
| מסיכת ביטים של דגלי מנפה שגיאות |
| תוצאת בלוק הקוד regex האחרון |
| מצב טיפול בחריגות (בתוך |
| שלב המפרש הנוכחי ( |
$] - גרסה מספרית#
ייצוג נקודה צפה של גרסת המפרש. פורמט: 5.PPPSSS כאשר PPP הוא הראשי ו־SSS הטלאי:
print "$]\n"; # e.g. "5.042000"
warn "old perl" if "$]" < 5.038;
warn "new perl" if "$]" >= 5.040;
המרת ה־"$]" למחרוזת לפני ההשוואה מומלצת - היא מתחמקת מבעיות ייצוג עדינות של נקודה צפה שיכולות לגרום ל־$] == 5.042 להיכשל באופן מסתורי.
הכינוי מ־English $OLD_PERL_VERSION מתועד אך לא מומלץ; $] עצמו תקין.
$^V - עצם גרסה#
גרסת המפרש כעצם version, מתאים לקריאה ולהשוואה עשירה יותר:
print "$^V\n"; # "v5.42.0"
warn "need 5.40+" if $^V lt v5.40.0;
הליטרל v5.40.0 הוא v-string - התחביר המקורי של Perl עבור קבועי גרסה. השתמשו ב־$^V בהשוואה לליטרלי v-string; השתמשו ב־$] בהשוואה למספריים חשופים.
ב־PetaPerl, $^V מדווח על רמת תאימות־Perl הבסיסית (5.42), לא על גרסת ההפצה של PetaPerl.
$^O - שם מערכת ההפעלה#
print "$^O\n"; # "linux"
if ($^O eq 'MSWin32') {
use_windows_path_separator();
}
PetaPerl הוא ל־Linux בלבד; $^O הוא תמיד "linux". המשתנה קיים לצורך תאימות־מקור עם קוד נייד המסתעף עליו. הרשימה המלאה של הערכים ש־Perl המקורי יכול להפיק כוללת את linux, darwin, freebsd, openbsd, MSWin32, cygwin, solaris, וכמה רשומות היסטוריות.
$^X - נתיב קובץ ההפעלה#
הנתיב למפרש הרץ כרגע, מתאים להפעלה מחדש:
print "$^X\n"; # e.g. "/usr/local/bin/pperl"
# Rerun the script under the same interpreter, with extra args:
exec $^X, $0, @ARGV, '--debug';
$^X הוא מה שהופך את exec $^X, $0, ... לנייד - אינכם צריכים לדעת אם הסקריפט הופעל דרך pperl, /usr/bin/env perl, או נתיב מוחלט.
$^T - basetime#
שניית ה־Unix epoch שבה התוכנית החלה לרוץ:
my $uptime = time() - $^T;
print "running for $uptime seconds\n";
השימוש הקלאסי הוא בדיקות הקובץ -M ו־-A, שכברירת מחדל מדווחות על גילאי קבצים יחסית ל־$^T ולא ל־time(). אם תקבעו $^T = time() מעת לעת, בדיקות קובץ אלה מחשבות מחדש מול נקודת הייחוס החדשה - שימושי בדמונים ארוכי־ריצה הצריכים להתעלם מקבצים ישנים מ“מאז שהתחלתי את האצווה הזו“.
$^W - מתג האזהרות#
דגל האזהרות הראשי, נקבע על ידי מתג שורת הפקודה -w:
$^W = 1; # all warnings on
$^W = 0; # all warnings off
$^W הוא הדגל הגלובלי מתקופת Perl-1. הפרגמה הלקסיקלית המודרנית use warnings היא הדרך המומלצת לשלוט באזהרות, והיא פועלת באופן עצמאי - בלוק use warnings נשאר פעיל ללא קשר ל־$^W, ובלוק no warnings נשאר כבוי ללא קשר ל־$^W. המשתנה חשוב בעיקר בקוד שקדם לפרגמה הלקסיקלית או שרוצה להחליף את ברירת המחדל הגלובלית בזמן ריצה.
${^WARNING_BITS} הוא המפת הביטים הלקסיקלית ש־use warnings קוראת וכותבת. הפורמט שלה פנימי; אל תסתמכו על מיקומי ביטים ספציפיים.
$^I - סיומת עריכה במקום#
נקבע על ידי מתג שורת הפקודה -i. כאשר $^I מוגדר, קריאה מ־<> (הצורה while (<>)) פותחת מחדש כל קובץ הן לקריאה והן לכתיבה ומפנה את ה־print הבא לקובץ הנכתב מחדש:
# perl -i.bak -ne 's/\bold\b/new/g; print' *.txt
# Equivalent in script form:
local $^I = '.bak';
while (<>) {
s/\bold\b/new/g;
print;
}
$^I = '' (מחרוזת ריקה) משמעו ”לכתוב מחדש במקום ללא גיבוי“. $^I = '.bak' שומר את המקור כ־<filename>.bak. קביעת $^I = undef מכבה את העריכה במקום.
$^P - מסיכת ביטים של דגלי מנפה שגיאות#
נקרא על ידי מנפה השגיאות של Perl; אם אינו אפס, DB::DB נקרא לפני כל הוראה. מנוהל על ידי perl -d ומשפחת המודולים Devel::* של מנפי שגיאות ו־profilers.
קוד משתמש נדיר קובע את $^P. ביטי הדגל מתועדים ב־perlvar המקורי; הערך הנפוץ ביותר שנראה הוא 0x73f (ניפוי שגיאות מלא).
$^R - תוצאת בלוק קוד regex#
התוצאה של היגד הקוד regex האחרון (?{...}) או (?(N)...). חי רק כל עוד ההתאמה העוטפת:
"abc123" =~ /(?<word>\w+?)(\d+)(?{ length($1) + length($2) })/;
print "$^R\n"; # 6 - the code block's last expression
PetaPerl תומך בבלוקי קוד regex (?{ }); ראו את פרק הביצועים של מדריך ה־regex עבור פרטי השפה.
$^S - מצב טיפול בחריגות#
מדווח האם המפרש נמצא כעת בתוך eval. הוא מחזיק אחד משלושה ערכים:
| משמעות |
|---|---|
| ניתוח מודול, |
| ריצה בתוך בלוק |
| בכל מקום אחר |
מצב ה־undef הוא החשוב: הוא יכול להופיע בתוך מטפל $SIG{__DIE__} או $SIG{__WARN__}, כאשר המפרש מהדר במקום לפעול. מטפל שצריך להתנהג אחרת במהלך ההידור בודק אותו:
local $SIG{__DIE__} = sub {
return if $^S; # real runtime exception - let it propagate
warn "compile-time failure: $_[0]";
};
השם הארוך הישן (use English) הוא $EXCEPTIONS_BEING_CAUGHT, שהוא מעט מטעה: ערך ה־undef אינו מציין האם חריגות נתפסות, משום שהידור התוכנית הראשית אינו תופס אותן.
${^GLOBAL_PHASE} - שלב המפרש הנוכחי#
שלב מחזור החיים הנוכחי של מפרש ה־Perl:
שלב | מתי |
|---|---|
| בתוך בנאי המפרש ברמת C |
| בלוקי |
| לאחר הידור, לפני |
| בלוקי |
| ביצוע התוכנית הראשית |
| בלוקי |
| הריסה גלובלית |
END {
if (${^GLOBAL_PHASE} eq 'END') {
log_shutdown(); # we are still in user END
}
}
# Inside a destructor, distinguish "object cleanup during normal
# scope exit" from "object cleanup during interpreter shutdown":
sub DESTROY {
my $self = shift;
if (${^GLOBAL_PHASE} eq 'DESTRUCT') {
# global destruction - order is undefined, file handles
# may already be torn down - be conservative
return;
}
$self->{handle}->flush;
}
משמר ה“אל תרוץ במהלך הריסה גלובלית“ בתוך DESTROY הוא מקרה השימוש הקלאסי של המשתנה. במהלך DESTRUCT, סדר פירוק העצמים אינו מוגדר; ההפניות של עצם עשויות להיות כבר לא־תקפות.
ראו גם#
use VERSION- הדרך המקובלת לדרוש גרסת Perl מינימלית, המחליפה אתif "$]" < ....require VERSION- זהה ל־use VERSIONאך בזמן ריצה.Config- תצורת הבנייה המלאה של Perl, עשירה הרבה יותר מ־$^Oו־$].use warnings- הפרגמה הלקסיקלית המחליפה את$^Wעבור קוד חדש.מתגי שורת פקודה - מתעד את
-i($^I),-w($^W),-d($^P).