הפניות אנונימיות - [...] ו־{...}#

לא תמיד רוצים לתת למערך או האש פנימיים שם לפני שמפנים אליהם. Perl מספק שני בנאים הבונים מכולה חדשה ומוסרים לכם הפניה אליה בביטוי בודד:

  • [...] בונה מערך אנונימי רענן ומחזיר הפניה אליו.

  • {...} בונה האש אנונימי רענן ומחזיר הפניה אליו.

אלה הדרך העיקרית שבה מבני נתונים מקוננים מורכבים.

מערך: [...]#

my $aref = [1, 'foo', undef, 13];

הצד הימני מעריך את הרשימה (1, 'foo', undef, 13), מקצה מערך חדש, מעתיק את ארבעת האלמנטים האלה לתוכו, ומספק סקלר המכיל הפניה לאותו מערך. זה בדיוק שווה־ערך לצורה הדו־שלבית עם ביניים בעל שם:

my @array = (1, 'foo', undef, 13);
my $aref  = \@array;

…אלא שאף משתנה @array אינו דולף לתחום הסובב. למערך האנונימי אין שם; רק ההפניה קיימת, והמערך נשאר חי כל עוד ההפניה קיימת.

צורות ריקות שימושיות כערכים התחלתיים:

my $aref = [];         # reference to a new empty array
push @{$aref}, 1, 2;   # now [1, 2]

האש: {...}#

my $href = { APR => 4, AUG => 8 };

אותו רעיון להאשים. הביטוי הוא רשימה של זוגות מפתח/ערך (ה־=> הוא רק פסיק שמצטט אוטומטית את צידו השמאלי), האש חדש מוקצה, הזוגות מוכנסים, ואתם מקבלים הפניה חזרה:

my %hash = (APR => 4, AUG => 8);
my $href = \%hash;

הוא השווה־ערך הדו־שלבי. וכמו עם מערכים, הצורה הריקה היא נקודת התחלה נפוצה:

my $href = {};
$href->{red} = 17;

{...} מול בלוק - פינה של הפענחן#

{...} חשוף במיקום הוראה מפוענח כבלוק, לא כבנאי האש:

{ foo => 1 };          # block, with `foo => 1` as its expression

ברוב המיקומים - מימין ל־=, בתוך רשימה, כארגומנט לפונקציה - Perl מבין את הקריאה של בנאי־ההאש אוטומטית. אם אי פעם תצטרכו לכפות את הפרשנות של בנאי־ההאש, שימו + לפניה:

my $x = +{ foo => 1 }; # unambiguous: always a hash reference

תזדקקו לכך לעיתים רחוקות. בתוך return +{...} מתת־שגרה ובמספר מיקומים ״דמויי־הוראה״ אחרים, זה התיקון.

קינון - בנאים בתוך בנאים#

מכיוון שכל בנאי מספק סקלר, וסקלרים הולכים לכל מקום, אתם מרכיבים מבנים על־ידי קינון:

my $tree = {
    name     => 'root',
    children => [
        { name => 'left',  children => [] },
        { name => 'right', children => [
            { name => 'r1', children => [] },
        ] },
    ],
};

print $tree->{children}[1]{children}[0]{name};   # r1

כל [...] ו־{...} מקצה רענן. בניגוד ל־foot-gun של ״מערך־פנימי־משותף״ מ־מערכים של מערכים, בנאים מקוננים אף פעם לא חולקים אחסון במקרה.

ביניים בעלי שם מול בנאים אנונימיים#

שתי הצורות עובדות. בחרו לפי קריאות:

  • בנאי אנונימי כאשר המכולה היא חד־מטרתית ותפקידה היחיד הוא ״להיות הערך של השדה הזה״. ליטרלי נתונים מקוננים, טבלאות חיפוש חד־פעמיות, רשומות בטבלת callbacks.

  • ביניים בעל שם כאשר אתם בונים את המכולה באופן אינקרמנטלי, או כאשר אתם רוצים להשתמש באופרטורי מערך/האש עליה ישירות מבלי לחזור על @{...} / %{...}:

    my @row;
    for my $x (@source) {
        push @row, transform($x);
    }
    $grid[$i] = \@row;
    

העתקה מול שיתוף#

בנאים אנונימיים תמיד מקצים; הם אף פעם לא חולקים. אך השמת הפניה אחת לסקלר אחר אינה משכפלת דבר:

my $a = [1, 2, 3];
my $b = $a;            # $a and $b refer to the SAME array
push @{$b}, 4;
print "@{$a}";         # 1 2 3 4

לקבלת העתק רדוד של המכולה הבסיסית, בצעו dereference בתוך בנאי רענן:

my $copy_aref = [ @{$a} ];     # new array, same elements
my $copy_href = { %{$h} };     # new hash, same keys/values

ההפניה החדשה עצמאית מהמקור. הערכים שבפנים עדיין משותפים - אם הערכים האלה הם עצמם הפניות, שני המבנים עדיין מצביעים על תת־עצים משותפים. זוהי העתקה רדודה. להעתקה עמוקה, פנו למודול כמו Storable (dclone).

לאן ממשיכים מכאן#

  • הפניות לתת־שגרה - הטעם השלישי של דבר אנונימי, באמצעות sub { ... } במקום [...] או {...}.

  • הפניות חלשות - נחוצות כאשר מבנה מקונן מצביע חזרה על עצמו.