Why can I get the address of a subroutine before it is declared without errors?

I have the following program:

use warnings;
use strict;

BEGIN {
    print \&mysub;
}


sub mysub {};

print \&mysub;

His conclusion:

CODE(0x118e890)CODE(0x118e890)

The block is BEGINprocessed at compile time. At this point, the definition sub mysubis not yet considered by the compiler. But the program still prints the right subroutine address, which it will have when determining.

Why am I not mistaken here? Is this some kind of autovivification?

+6
source share
2 answers

Yes, this is a form of autovivitation. A piece is created when a reference to sub is required, but sub does not exist.

use strict;
use warnings qw( all );
use feature qw( say );

sub test {
   say  defined(&mysub) ? "defined (".\&mysub.")"
      : exists(&mysub)  ? "exists (".\&mysub.")"
      :                   "doesn't exist";
}

test();
my $ref = \&mysub;
test();
eval("sub mysub { }  1") or die($@);
test();

Output:

doesn't exist
exists (CODE(0xab8cd8))
defined (CODE(0xab8cd8))
+4
source

. , , , .

, .

Devel::Peek , .

:

use warnings;
use strict;
use Devel::Peek;

$|++;

BEGIN {
  Dump( \&mysub );
  print \&mysub;
};

sub mysub {};

Dump( \&mysub );
print \&mysub;

$|++, Devel::Peek::Dump \&mysub. :

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)

, Dump . Dump . , , , , , : PADLIST ( null), PADNAME START ( Perl guts, , "" ).

, . , , .

+2

All Articles