| > In Perl [...] pragmas are language level No, actually. The syntax that people use to invoke the pragma ("use strict [arg]...") is not a pragma at the language level, it's just the syntax for importing symbols from modules. For example, use strict ('vars', 'refs');
expands to BEGIN { require 'strict'; strict->import('vars', 'refs'); }
because that's how the "use" statement is defined. `BEGIN{...}` cause the statements in the block to be executed as soon as the BEGIN block has been fully parsed [1]. `require 'strict'` loads the module `strict.pm` from the library path (the source code is on CPAN at [2], if you're interested), then its `import()` method is called with two string arguments. The implementation of that method is: sub import {
shift;
$^H |= @_ ? &bits : all_bits | all_explicit_bits;
}
There's a lot of weird Perl syntax in there, but the gist is that it modifies the $^H variable. And THAT is the actual pragma which is defined by the language. [3] The module strict.pm is just a wrapper around $^H to make things a bit more user-friendly.I know that's sorta kinda off-topic, but since we're talking about language design, I figured I'd contribute this small anecdote that illustrates really well how the more recent parts of Perl are designed: a ton of metaprogramming on top of relatively small changes to the core language. If you want another example, have a look at how object-oriented programming was tacked on to Perl as a tiny afterthought, yet the way it interacts with all the other parts of the language makes hugely powerful OOP frameworks like Moose possible. (OTOH, that approach also makes the language pretty messy, but it always gets the job done for me, at many scales.) [1] Usually, execution only begins when the entire file has been parsed, but this code needs to run earlier because it changes the parser's behavior. [2] https://metacpan.org/source/SHAY/perl-5.26.1/lib/strict.pm [3] Notably, $^H behaves differently from other variables: Every assignment to it is scoped only to the current block, whereas regular variables need to be shadowed explicitly. This is particularly useful to temporarily lift a strictness requirement for a single statement, similar to how `unsafe` is used in Rust: use strict;
...
my $function_name = 'implementation_' . ($x + 2 * $y);
$function_name(); //error: cannot call string value
{
no strict 'refs'; //"no" is like "use", but in reverse (calls the module's unimport() instead of import())
$function_name(); //works: calls the function with the name stored in the variable
}
|