אופרטור החץ#

האופרטור הנמצא בשימוש האינטנסיבי ביותר ב־Perl מעשי, אחרי =. הוא עושה שלושה דברים בשלושה מיקומים תחביריים, וכולם מתחילים בderef של משהו בצד שמאל.

צורה

משמעות

דוגמה

$ref->[i]

אלמנט של arrayref

$aref->[0]

$ref->{k}

אלמנט של hashref

$href->{name}

$ref->(...)

קריאה ל־coderef

$cref->(@args)

$obj->meth

קריאה למתודה על עצם

$obj->print

$obj->meth(@a)

קריאה למתודה עם ארגומנטים

$obj->set_x(42)

$class->meth

קריאה למתודת מחלקה

Foo::Bar->new

שלוש הצורות הראשונות הן 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 (@{...}, %{...}, ${...}) מתחברות.