namespaces - Perl: prototype in anonymous subroutine -
i learning perls system of typeglobs , namespaces. wrote module takes 2 arguments value , name of constant , exports constant caller. $package variable equal caller[2].
*{"$package::$name"} = sub () { return $value; };
this code above job of exporting anonymous subroutine callers symboltable. because goal build own constant-implementation subroutine has empty prototype means read-only subroutine.
but problem: prototype not work. so
print &testconst; #works print testconst(); #works print testconst; #name "main::testconst" used once: possible typo @ testscript.pl line 7.
is there wrong in thoughts? there way of doing it?
you can define symbols want during runtime, prototypes affect code compiled afterwards since prototypes affect how calls sub parsed , compiled. example:
use strict; use warnings; package foo; begin { *foo::bar = sub () { 42 }; } *foo::baz = sub () { 43 }; $bar = bar; $baz = baz; print "bar = [$bar], baz = [$baz]\n";
if run this, dies with:
bareword "baz" not allowed while "strict subs" in use @ tprot.pl line 13.
that's compile-time error caused strict
: compiler saw symbol baz
, didn't know was, because typeglob *foo::baz
not altered until runtime. bar
worked fine because defined in begin
block, executes during compilation.
iow, because barewords ambiguous, perl needs know @ compile-time whether it's sub or else. can install these during import
(which executes in implicit begin
block) not @ runtime.
additionally, prototypes affect compilation semantics; constant subroutine (like made constant.pm
) gets optimized away. other prototypes cause parser change behavior (e.g. subs can take code blocks.) compiler has know stuff before calls sub encountered in code, can parsed correctly. code runs after parsed.
calling sub explicit parens or ampersand not have restriction because perl smart enough @ runtime know these subroutine calls, , them dynamically in symbol table.
Comments
Post a Comment