Arrow operator#
The single most heavily used operator in working Perl, after =. It does three things at three syntactic positions, and they all start by dereferencing something on the left.
Form | Means | Example |
|---|---|---|
| element of an arrayref |
|
| element of a hashref |
|
| call a coderef |
|
| method call on an object |
|
| method call with arguments |
|
| class method call |
|
The first three forms are dereferencing. The last three are method dispatch. Both are spelled with ->.
Dereferencing#
A reference is a scalar that points at a container or a coderef. You cannot index into a reference directly with [] or {}; you must dereference first, and -> is the canonical way:
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 invocation#
my $f = sub { $_[0] * 2 };
$f->(5) # 10 — invoke the coderef with argument 5
&$f(5) # same — older syntax, still works
The ->() form is preferred in modern Perl. Empty argument list is $f->().
Arrow elision between subscripts#
When two subscripts directly follow each other on a deref chain, the second arrow can be omitted. The grammar implies it:
$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
The first arrow (between a scalar variable and the first subscript) is required. Only arrows between consecutive subscripts may be elided.
$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!
The first-arrow rule is the source of subtle bugs when refactoring $aref->[0] into a deeper expression — keep the leading arrow.
Method calls#
When the right side of -> is an identifier (or a parenthesised name expression), it is interpreted as a method call rather than a subscript:
$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?
Method calls dispatch through the package the object is blessed into. The exact resolution path is governed by @ISA and the chosen MRO; see the OOP guide for the full story.
Indirect-object syntax — don’t use it#
Perl 5 historically allowed print $fh "foo" and new Foo @args without an arrow. These forms still parse but are context-sensitive in ways that surprise — the indirect-object syntax can resolve the new (or whatever) at the wrong time. The modern guidance is to always use -> for method calls:
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
Precedence#
-> is row 2 of the precedence table — second only to terms and list operators. It binds tighter than every other operator, which is what you want: $h->{a} + $h->{b} parses as the sum of two hash lookups, not as a lookup of {a + $h->{b}}.
See also#
Subscript — direct (non-dereferenced) array/hash access; the arrow-elision rule.
References tutorial — full treatment of references, including how
\builds them and how the deref alternatives (@{...},%{...},${...}) work.OOP guide —
->methodand class dispatch in depth.ref,bless— perlfunc tools that pair with the arrow operator’s two roles.References — what
\Xproduces and how the deref shapes (@{...},%{...},${...}) compose.