אופרטור החץ#
האופרטור הנמצא בשימוש האינטנסיבי ביותר ב־Perl מעשי, אחרי =. הוא עושה שלושה דברים בשלושה מיקומים תחביריים, וכולם מתחילים בderef של משהו בצד שמאל.
צורה | משמעות | דוגמה |
|---|---|---|
| אלמנט של arrayref |
|
| אלמנט של hashref |
|
| קריאה ל־coderef |
|
| קריאה למתודה על עצם |
|
| קריאה למתודה עם ארגומנטים |
|
| קריאה למתודת מחלקה |
|
שלוש הצורות הראשונות הן deref. שלוש האחרונות הן דיספאץ« מתודה. שתיהן נכתבות עם ->.
Dereferencing#
הפניה היא סקלר שמצביע על מכל או על coderef. אינכם יכולים לאנדקס לתוך הפניה ישירות עם [] או {}; עליכם לבצע deref תחילה, ו־-> היא הדרך הקנונית:
my @arr = (10, 20, 30);
my $aref = \@arr;
$arr[0] # 10 - direct array access
$$aref[0] # 10 - dereference, then subscript (old syntax)
$aref->[0] # 10 - dereference and subscript in one move
$aref->[-1] # 30 - negative indices work the same way
my %h = (name => 'John');
my $href = \%h;
$h{name} # 'John'
${$href}{name} # 'John' - full deref + subscript
$href->{name} # 'John' - same, idiomatic form
הפעלת coderef#
my $f = sub { $_[0] * 2 };
$f->(5) # 10 - invoke the coderef with argument 5
&$f(5) # same - older syntax, still works
הצורה ->() מועדפת ב־Perl מודרני. רשימת ארגומנטים ריקה היא $f->().
השמטת חץ בין מציינֵי־מקום#
כששני מציינֵי־מקום עוקבים זה אחר זה ישירות בשרשרת deref, ניתן להשמיט את החץ השני. הדקדוק מרמז עליו:
$grid[1]->[2] # explicit
$grid[1][2] # arrow elided - the only way most people write this
$tree->{children}[0]{name} # parses with arrows between every pair
# - the chain is read as a sequence
# of subscripts on the same deref path
החץ הראשון (בין משתנה סקלר לבין מציין־המקום הראשון) הוא חובה. רק חצים בין מציינֵי־מקום עוקבים ניתנים להשמטה.
$aref->[0]->[1] # explicit
$aref->[0][1] # elided second arrow - fine
$aref[0][1] # WRONG - $aref[0] reads from @aref, not the
# arrayref in $aref. Different variable!
כלל החץ הראשון הוא מקור לבאגים עדינים בעת ארגון מחדש של $aref->[0] לכדי ביטוי עמוק יותר - שמרו על החץ המוביל.
קריאות למתודה#
כשהצד הימני של -> הוא מזהה (או ביטוי שם בסוגריים), הוא מתפרש כקריאה למתודה ולא כמציין־מקום:
$obj->print; # call $obj->print()
$obj->name; # accessor: returns $obj->name
$obj->set_name("Alice"); # mutator: sets and may return $obj
Foo::Bar->new(arg => 1); # class method call
$obj->$method_name(@args); # method name in a variable
$class->can('foo') # can() - does method exist?
קריאות למתודה מבצעות דיספאץ« דרך החבילה שאליה ה־blessed העצם. נתיב הרזולוציה המדויק נשלט על־ידי @ISA וה־MRO הנבחר; ראו את מדריך ה־OOP לסיפור המלא.
תחביר עצם־עקיף - אל תשתמשו בו#
Perl 5 התיר בעבר print $fh "foo" ו־new Foo @args ללא חץ. צורות אלה עדיין מפוענחות אך הן רגישות־הקשר בדרכים שמפתיעות - תחביר העצם־העקיף יכול לפתור את new (או כל דבר אחר) בזמן הלא־נכון. ההנחיה המודרנית היא תמיד להשתמש ב־-> לקריאות למתודה:
my $obj = Foo->new(@args); # correct
my $obj = new Foo @args; # avoid (still parses)
print $fh "hello\n"; # OK - print is special
$fh->print("hello\n"); # also fine, prefer this
# for IO::File-style handles
קדימות#
-> הוא שורה 2 בטבלת הקדימות - שני רק למונחים ולאופרטורי רשימה. הוא נקשר בחוזקה רבה יותר מכל אופרטור אחר, וזה מה שאתם רוצים: $h->{a} + $h->{b} מפוענח כסכום של שני חיפושי האש, לא כחיפוש של {a + $h->{b}}.
ראו גם#
מציין־מקום - גישה ישירה (ללא deref) למערך/האש; כלל השמטת־החץ.
הדרכת הפניות - טיפול מלא בהפניות, כולל כיצד
\בונה אותן וכיצד חלופות ה־deref (@{...},%{...},${...}) פועלות.מדריך OOP -
->methodודיספאץ« מחלקה לעומק.ref,bless- כלי perlfunc המתחברים בצמד עם שני תפקידיו של אופרטור החץ.הפניות - מה
\Xמייצר וכיצד צורות ה־deref (@{...},%{...},${...}) מתחברות.