use strict;
use warnings;
sub test_a;
sub test_a { my $arg = shift; ref($arg) ? test_a$$arg[0] : $arg }
sub test_b { my $arg = shift; ref($arg) ? test_a$$arg[0] : $arg }
print test_b[42]; # prints '42'
print test_a[42]; # prints '42'
The reason your original one fails is that while perl is parsing the body of sub test_a, it encounters test_a$$arg[0] and isn't quite sure how to parse it. You'd want to parse it like:
test_a($$arg[0])
But it actually gets parsed like this:
${ $arg }->test_a([0])
That is, it assumes you're calling the test_a method on $$arg via the indirect method syntax.
It makes this assumption because while the body of test_a is being parsed, there is no function called test_a in the symbol table. So it assumes that you cannot really mean test_a($$arg[0]).
Pre-declaring sub test_a; (as per my example) solves this. The other solution is to avoid the ambiguity in your syntax and add parentheses.
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
|