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.