Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are Perl's lexically-scoped pragmas implemented?

Pragmas, like autodie, according to the docs, are lexically scoped.

{
use autodie;
  ..
  ..
}
# Can die here

Does this apply to all modules loaded with use? As far as I know, use is almost the same as:

BEGIN {
  require autodie;
  autodie->import(LIST);
}

BEGIN happens at compile time, and require is not lexically scoped. So how is autodie aware of its scope?

like image 285
snoofkin Avatar asked Jul 29 '12 18:07

snoofkin


2 Answers

The short answer is that lexically-scoped pragmatic modules are explicitly written to behave that way, and use the magical internal variables $^H and %^H during compile time to enable and disable features.

The compiler plays its part by implicitly localising these variables so their value is restored at the end of compiling a code block to what it was at the start. In that way it provides the basis of lexical semantics.

Originally only the $^H variable was available. It contains a bit mask that dictates which compiler options are available at any time during the compilation. Because of that the only lexical pragmas that could be written were ones that manipulated the defined set of magic bits in $^H.

Later the %^H hash was introduced, and any pragma can now store values in this hash with keys that start with the name of the pragma. Because the compiler localises the hash in the same way as the scalar, any pragma can store automatically scoped status information here.

The autodie module doesn't manipulate either of these variables, but subclasses the Fatal module which does all the hard work. It uses %^H to keep track of which operators have been made fatal, and relies on the compiler to discard this information at the end of the block.

like image 177
Borodin Avatar answered Nov 02 '22 21:11

Borodin


From the import method of Fatal.pm which is the backend of autodie, enjoy this:

# Dark magic to have autodie work under 5.8
# Copied from namespace::clean, that copied it from
# autobox, that found it on an ancient scroll written
# in blood.

# This magic bit causes %^H to be lexically scoped.
$^H |= 0x020000;

So the answer is there really is a way to make your imports aware of their lexical scope, but it's deeply entangled with the guts of perl and not meant for ordinary programmers to use.

like image 42
Alan Curry Avatar answered Nov 02 '22 22:11

Alan Curry