Very interesting question. I'm writing this as an answer instead of a comment because it will be rather long, but there are still some bits I'm not entirely sure about.
I believe your intuition is correct and that it is a form of autovivification.
Devel::Peek can spread more light on what's happening.
I changed your code a little bit:
use warnings;
use strict;
use Devel::Peek;
$|++;
BEGIN {
Dump( \&mysub );
print \&mysub;
};
sub mysub {};
Dump( \&mysub );
print \&mysub;
I added $|++
so that buffering won't be cause of confusions, and added calls to Devel::Peek::Dump
to look into the reference \&mysub
. Here the output on my system:
SV = IV(0x2628628) at 0x2628638
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x26286e0
SV = PVCV(0x2640750) at 0x26286e0
REFCNT = 2
FLAGS = (DYNFILE)
COMP_STASH = 0x25ffdb0 "main"
ROOT = 0x0
GVGV::GV = 0x26287a0 "main" :: "mysub"
FILE = "/tmp/autov.pl"
DEPTH = 0
FLAGS = 0x1000
OUTSIDE_SEQ = 0
PADLIST = 0x0
OUTSIDE = 0x0 (null)
CODE(0x26286e0)SV = IV(0x25fff20) at 0x25fff30
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x26286e0
SV = PVCV(0x2640750) at 0x26286e0
REFCNT = 2
FLAGS = (DYNFILE)
COMP_STASH = 0x25ffdb0 "main"
START = 0x262ea50 ===> 1
ROOT = 0x262ea10
GVGV::GV = 0x26287a0 "main" :: "mysub"
FILE = "/tmp/autov.pl"
DEPTH = 0
FLAGS = 0x1000
OUTSIDE_SEQ = 371
PADLIST = 0x2648620
PADNAME = 0x2630180(0x2667f70) PAD = 0x2628770(0x262f020)
OUTSIDE = 0x2600140 (MAIN)
CODE(0x26286e0)
Note how Dump
's output changes between the two calls.
The first time Dump
is called we just have a reference to a empty scalar.
The second time, after the actual definition of the subroutine, you can see the details that pertain to subroutines have been fleshed out: namely PADLIST
(now not null), PADNAME
and START
(I'm not an expert of Perl guts but I think this is the actual "pointer" to the subroutine).
I hope this helps. I'd be interested in knowing what you'll discover if you'll dig deeper in the problem.
BEGIN {}
and it still prints the address and no warnings or errors. However if you try to call the sub afterwards (without defining it), you getUndefined subroutine &main::mysub
, so it is not autovivified. Seems like a bug. – Milena