Skip to content

Commit 8bfeb77

Browse files
committed
PPC0033: method-like calls to lexical subs
Add a syntax $object->&method(@Args) that calls method as a sub, to allow a nicer syntax for private methods.
1 parent 8ff6f03 commit 8bfeb77

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Allow calling subs using method-like syntax
2+
3+
## Preamble
4+
5+
Author: Graham Knop <[email protected]>
6+
ID: 0033
7+
Status: Draft
8+
9+
## Abstract
10+
11+
Add a syntax for calling lexical methods that is similar to the existing
12+
method syntax, rather than needing to call them like subs. The new syntax
13+
`$object->&method(@args)` would be equivalent to sub call to `method`, but
14+
using a syntax closer to method calls.
15+
16+
## Motivation
17+
18+
When using a lexical sub inside an object class, the subs must be called as
19+
`method($object, @args)`. This works, but for many people, this feels wrong
20+
as a way to call something thought of as a private method. This has resulted
21+
in some people using syntax like `$object->${\&method}(@args)`, or continuing
22+
to use code refs stored in a lexical variable.
23+
24+
## Rationale
25+
26+
`$object->method(@args)` always does a method lookup, ignoring the local
27+
context. Changing this would result in a lot of broken code. Changing this
28+
only for new code (via feature or other lexical effect) would introduce
29+
confusion and would also require some new (or pessimised) syntax to allow
30+
the previous behavior.
31+
32+
`$object->&method(@args)` would be an unambiguous way to call the `method` in
33+
the current scope, whether a lexical or package sub.
34+
35+
A truly private method does not need to do any lookup via `@ISA`, so being
36+
equivalent to a sub call makes sense.
37+
38+
This also would pair well with
39+
[PPC0021](ppc0021-optional-chaining-operator.md) to allow optional sub calls
40+
as part of a chain.
41+
42+
## Specification
43+
44+
`$object->&method(@args)` would behave exactly the same as `&method($object,
45+
@args)`. `method` would be searched for in the current lexical scope. If not
46+
found, it would be looked up in the current package. If still not found, the
47+
current package's `AUTOLOAD` would be called. If `AUTOLOAD` does not exist, an
48+
error would be issued. The call would ignore prototypes, just as traditional
49+
method calls and `&subroutine()` calls do.
50+
51+
## Backwards Compatibility
52+
53+
The syntax `->&word` is currently a syntax error, so no backwards
54+
compatibility issues are forseen.
55+
56+
## Security Implications
57+
58+
As this is purely a syntax feature that is currently a syntax error, no
59+
security implications are forseen.
60+
61+
## Examples
62+
63+
```perl
64+
use v5.36;
65+
66+
package Foo {
67+
sub new ($class) {
68+
return bless {
69+
field => 5,
70+
}, $class;
71+
}
72+
73+
my sub private ($self) {
74+
return $self->{field};
75+
}
76+
77+
sub _old_school_private ($self) {
78+
return $self->{field};
79+
}
80+
81+
sub public ($self) {
82+
83+
# call via lexical method is allowed
84+
say "my field: " . $self->&private;
85+
# exactly equivalent to:
86+
say "my field: " . private($self);
87+
88+
89+
# can also be used to call package methods. But won't lookup via @ISA
90+
say "my field: " . $self->&_old_school_private;
91+
# exactly equivalent to:
92+
say "my field: " . _old_school_private($self);
93+
}
94+
}
95+
96+
my $foo = Foo->new;
97+
$foo->public;
98+
99+
# this is an error, as there is no sub named private in scope
100+
$foo->&private;
101+
```
102+
103+
## Prototype Implementation
104+
105+
None currently.
106+
107+
## Future Scope
108+
109+
This syntax would also make sense to use for private method calls in the
110+
`class` syntax.
111+
112+
## Rejected Ideas
113+
114+
Allowing `$object->method` to call lexical subs would break existing code and
115+
would interfere with the ability to call the actual method. Perl doesn't know
116+
what type `$object` is, so it can't know when it is appropriate to do method
117+
lookup and when to call a local sub. Using a different syntax at the call site
118+
avoids these issues.
119+
120+
## Open Issues
121+
122+
None currently.
123+
124+
## Copyright
125+
126+
Copyright (C) 2025, Graham Knop
127+
128+
This document and code and documentation within it may be used, redistributed
129+
and/or modified under the same terms as Perl itself.

0 commit comments

Comments
 (0)