my#
מצהיר על משתנה אחד או יותר בתיחום לקסיקלי.
my introduces new variables whose visibility is bounded by the enclosing block, file, or eval. The compiler records the declaration at compile time; the storage is allocated and (re)initialised each time control enters the scope. Unlike local, my does not temporarily replace a package variable
it creates a genuinely new variable that exists only while the scope is live and is invisible outside it, including to any subroutines the scope calls.
תקציר#
my EXPR
my TYPE EXPR
my EXPR : ATTRS
my TYPE EXPR : ATTRS
משתנה יחיד עשוי להיכתב ללא סוגריים; רשימה של שניים או יותר חייבת להיות בסוגריים:
my $x;
my ($a, $b, @rest);
my Foo $obj;
my $x : shared = 0;
מה מקבלים בחזרה#
my היא הצהרה, לא אופרטור מייצר־ערך במובן הרגיל. במיקום rvalue היא מניבה את המשתנה שלה (או את רשימת המשתנים) כ־lvalue שניתן להשים אליו. הניבים הנפוצים הם:
my $x = $expr; # scalar context on RHS
my ($first, @rest) = @list; # list context on RHS; destructuring
my @copy = @src; # list context; @copy gets the elements
my %h = @pairs; # list context; pairs populate the hash
כשלא ניתן מאתחל, כל משתנה מוצהר מתחיל כ־undef (סקלר), רשימה ריקה (מערך), או האש ריק.
תיחום ותוחלת חיים#
תיחום בלוק. משתנה
myנראה מהנקודה שמיד אחרי הצהרתו עד סוף הבלוק העוטף הפנימי ביותר, הקובץ,eval,do,require, או קובץ שעברuse.תיחום ביטוי־בקרה. הביטוי השולט של
if/unless/elsif/else,while/until,for/foreachהוא חלק מהתיחום של ההצהרה הכלולה בו. ב־while (my $line = <$fh>) { ... }המשתנה$lineחי לאורך כל גוף הלולאה ובלוק ה־continueשלה, אך לא מעבר לכך.אחסון רענן בכל כניסה. בכל פעם שהבקרה נכנסת מחדש לתיחום, המשתנה נוצר מחדש. זה ההבדל המרכזי מ־
state, השומר על ערכו לאורך כניסות.Closures לוכדים אחסון, לא ערכים. תת־שגרה אנונימית הנוצרת בתוך התיחום שומרת על אותו מופע מסוים של המשתנה בחיים כל עוד התת־שגרה ניתנת לגישה.
sub make_counter {
my $n = 0;
return sub { ++$n }; # closes over this $n
}
my $c = make_counter();
$c->(); $c->(); # 1, 2
צורת רשימה ופירוק#
עם סוגריים, my מספקת הקשר רשימה לצד ימין ומפרקת את התוצאה:
my ($sec, $min, $hour) = localtime;
my ($head, @tail) = @list; # @tail absorbs the rest
my ($x, $y) = ($y, $x); # swap via list assignment
יש להשתמש ב־undef כמציין מקום כדי לדלג על מיקום:
my (undef, $min, $hour) = localtime; # discard seconds
ללא סוגריים, my $foo היא הצהרת משתנה יחיד ואופרטור הפסיק חל על מה שבא אחריו:
my $foo, $bar = 1; # WRONG: declares $foo only;
# $bar is the package variable
my ($foo, $bar) = (0, 1); # Right.
מלכודות הקשר#
my אינה משנה איך הצד הימני מוערך - היא רק משנה את המשתנה בשמאל. my $foo סקלרי כופה הקשר סקלר; my (...) בסוגריים כופה הקשר רשימה:
my $line = <$fh>; # scalar context: one line
my ($line) = <$fh>; # list context: first of a list
my @lines = <$fh>; # list context: all remaining lines
הטעות הקלאסית היא כתיבת my ($foo) = <$fh> כאשר רצו שורה יחידה - הסוגריים מפעילים הקשר רשימה ומטפל הקובץ מחזיר רשימה בת איבר אחד; הערך במקרה הוא השורה הראשונה, אך ההקשר הסובב שגוי עבור כל מה שיבוא אחריו.
my מול local מול our מול state#
ארבע הצהרות, ארבע משמעויות שונות:
my- מציג משתנה לקסיקלי חדש. אינו נראה לקוד הנקרא. אחסון רענן בכל כניסה.local- אינה מצהירה על דבר. היא שומרת את הערך הנוכחי של משתנה חבילה קיים ומחזירה אותו כאשר התיחום העוטף יוצא. נראה לקוד הנקרא דרך תיחום דינמי. יש להשתמש בו עבור החופן של גלובלים קסומים ($_,$/,$\,$,,$|,%ENV, …) שלא ניתן להפוך ללקסיקליים.our- מצהיר על כינוי לקסיקלי למשתנה חבילה (גלובלי). האחסון חי בטבלת הסמלים של החבילה;ourרק מאפשרת להתייחס אליו ללא קידומת החבילה לשאר התיחום הלקסיקלי. מספק אתuse strict 'vars'.state- כמוmyבנראות, אך האחסון נשמר לאורך כניסות חוזרות לתיחום. אתחול רץ פעם אחת; כניסות עוקבות משאירות את הערך בשקט.
package Counter;
our $total = 0; # package global; $Counter::total
my $cache; # lexical; invisible outside this file
state $calls = 0; # lexical; keeps its value across calls
sub tick {
local $\ = "\n"; # temporarily override output separator
++$calls;
print ++$total;
}
נקודה קריטית: my $var אינו מסווה משתנה חבילה בעל אותו שם. משתנה החבילה נשאר נגיש דרך הצורה המוסמכת במלואה שלו כל עוד הלקסיקלי בתיחום:
package main;
our $x = 10;
my $x = 20;
print "$x and $::x\n"; # "20 and 10\n"
TYPE ותכונות#
שתי הצורות הן חלק מהשפה אך הסמנטיקה שלהן עדיין מתפתחת (ניסוח המקור).
TYPE - שם מחלקה כ־bareword, קבוע שהוצהר דרך
use constant, או__PACKAGE__. היסטורית נכבל ל־pragma שלfields; לשימוש רגיל הוא משמש כרמז ואינו אוכף טיפוס בזמן ריצה.my Foo $obj = Foo->new;
ATTRS - רשימת תכונות המוצגת בנקודתיים המטופלת על ידי ה־pragma של
attributes(ו־Attribute::Handlersמאז 5.8.0).my $x : shared; my @buf : Locked;
ראו L<perlsub/“Private Variables via my()“> במקור לניסוח הסמכותי.
ההצהרה עדיין לא בתיחום ב־RHS של עצמה#
המשתנה החדש המוצהר אינו נראה עד לאחר סיום המשפט המצהיר. זה הופך את הניב הזה למוגדר היטב:
my $x = $x; # new $x initialised from the old $x
ותנאי זה תלוי ב־$x חיצוני קיים מראש:
my $x = 123 and $x == 123; # false unless the old $x was 123
בתוך משפט יחיד, אזכורים נוספים של השם מתייחסים לכבילה שלפני ההצהרה (או מעלים שגיאת strict 'vars' אם אין כבילה כזו):
our $x = 2;
foo($x, my $x = $x + 1, $x); # foo() receives (2, 3, 2)
דוגמאות#
כניסה טיפוסית לתת־שגרה - מתן שמות לארגומנטים:
sub distance {
my ($x1, $y1, $x2, $y2) = @_;
return sqrt( ($x2-$x1)**2 + ($y2-$y1)**2 );
}
אינדקס מקומי ללולאה עם for my:
for my $i (1 .. 10) {
# $i is fresh each iteration; invisible after the loop
}
מצב פרטי בתיחום קובץ - המשתנה קיים למשך חיי המפרש אך אינו נגיש מחוץ לקובץ הזה:
my $cache = {};
sub lookup { $cache->{ $_[0] } //= _compute($_[0]) }
תת־שגרה פרטית דרך coderef לקסיקלי:
my $helper = sub { ... };
$helper->($x);
אזהרת הסתרה - הצהרה מחדש באותו תיחום מנפיקה אזהרה בקטגוריית shadow תחת use warnings:
use warnings 'shadow';
my $x = 1;
my $x = 2; # warning: "my" variable $x masks ...
מקרי קצה#
רק מזהים אלפא־נומריים. מובנים קסומים כגון
$/,$_,$\,%ENV,@ARGVלא ניתן להפוך ללקסיקליים. יש להשתמש ב־localכדי לתחם אותם דינמית.אין הסמכת חבילה.
my $Foo::barהיא שגיאת תחביר: משתניmyאינם בבעלות חבילה ואינם יכולים לשאת מסמיך::.סוגריים חסרים סביב רשימה.
my $a, $bמצהיר רק על$a;$bהוא משתנה החבילה. יש להקיף בסוגריים תמיד שני שמות או יותר.הפתעת הקשר רשימה.
my ($line) = <$fh>כופה הקשר רשימה על הקריאה; ה־RHS היא רשימה בת איבר אחד, לא סקלר. יש להשמיט את הסוגריים אם רוצים סמנטיקה סקלרית.foreachללאmy.for $i (...)ממקמת את$iדינמית באופןlocal. עדיףfor my $i (...)כדי לתחום את האינדקס לקסיקלית.הסתרה בלולאות.
myבתוך גוף לולאה מצהיר על משתנה רענן בכל איטרציה. אם זה לא רצוי (לדוגמה, מונה שצריך לשרוד איטרציות), יש להצהיר עליו מחוץ ללולאה או להשתמש ב־state.לכידת closure. closure על משתנה
myשומר על אותו מופע מסוים בחיים. קריאות שונות לתת־שגרה עוטפת מייצרות closures עצמאיים על משתנים עצמאיים.אינטראקציה עם
use strict 'vars'.myמספקת strict-vars בתוך התיחום שלה; משתנים ללא הצהרה חייבים להיותour, מוסמכים במלואם, או מוצהרים מראש עםuse vars.זמן הידור מול זמן ריצה. כבילת השם מתרחשת בזמן הידור; המאתחל רץ בזמן ריצה, ורץ מחדש בכל כניסה לתיחום. מאתחלים יקרים בתוך לולאות חמות משלמים את העלות הזו בכל איטרציה.
הבדלים מהמקור#
תואם במלואו ל־Perl 5.42 במקור.
ראו גם#
our- כינוי לקסיקלי למשתנה חבילה; מספק אתstrict 'vars'מבלי ליצור אחסון חדשlocal- שמירה/שחזור בתיחום דינמי של משתנה חבילה קיים; הכלי לגלובלים קסומיםstate- לקסיקלי כמוmy, אך אחסון נשמר לאורך כניסות חוזרות לתיחוםundef- מציין מקום ברשימתmyבסוגריים, והערך ההתחלתי של סקלר לא־מאותחלuse strict- הופך אתmy/our/ שמות מוסמכים במלואם לחובה, תופס גלובלים בשוגגattributes- pragma המפרש את החלק: ATTRSשל הצהרתmy