NAME¶
Devel::Pragma - helper functions for developers of lexical pragmas
SYNOPSIS¶
package MyPragma;
use Devel::Pragma qw(:all);
sub import {
my ($class, %options) = @_;
my $hints = my_hints; # lexically-scoped %^H
my $caller = ccstash(); # currently-compiling stash
unless ($hints->{MyPragma}) { # top-level
$hints->{MyPragma} = 1;
# disable/enable this pragma before/after compile-time requires
on_require \&teardown, \&setup;
}
if (new_scope($class)) {
...
}
my $scope_id = scope();
}
DESCRIPTION¶
This module provides helper functions for developers of lexical pragmas. These
can be used both in older versions of perl (from 5.8.1), which have limited
support for lexical pragmas, and in the most recent versions, which have
improved support.
EXPORTS¶
"Devel::Pragma" exports the following functions on demand. They can
all be imported at once by using the ":all" tag. e.g.
use Devel::Pragma qw(:all);
my_hints¶
Until perl change #33311, which isn't currently available in any stable perl
release, values set in %^H are visible in files compiled by "use",
"require" and "do FILE". This makes pragmas leak from the
scope in which they're meant to be enabled into scopes in which they're not.
"my_hints" fixes that by making %^H lexically scoped i.e. it
prevents %^H leaking across file boundaries.
"my_hints" installs versions of perl's "require" and
"do FILE" builtins in the currently-compiling scope which clear %^H
before they execute and restore its values afterwards. Thus it can be thought
of a lexically-scoped backport of change #33311.
Note that "my_hints" also sets the $^H bit that "localizes"
(or in this case "lexicalizes") %^H.
The return value is a reference to %^H.
new_scope¶
This function returns true if the currently-compiling scope differs from the
scope being compiled the last time "new_scope" was called.
Subsequent calls will return false while the same scope is being compiled.
"new_scope" takes an optional parameter that is used to uniquely
identify its caller. This should usually be supplied as the pragma's class
name unless "new_scope" is called by a module that is not intended
to be subclassed. e.g.
package MyPragma;
sub import {
my ($class, %options) = @_;
if (new_scope($class)) {
...
}
}
If not supplied, the identifier defaults to the name of the calling package.
scope¶
This returns an integer that uniquely identifies the currently-compiling scope.
It can be used to distinguish or compare scopes.
A warning is issued if "scope" (or "new_scope") is called in
a context in which it doesn't make sense i.e. if the scoped behaviour of
"%^H" has not been enabled - either by explicitly modifying $^H, or
by calling "my_hints" or "on_require".
ccstash¶
This returns the name of the currently-compiling stash. It can be used as a
replacement for the scalar form of "caller" to provide the name of
the package in which "use MyPragma" is called. Unlike
"caller", it returns the same value regardless of the number of
intervening calls before "MyPragma::import" is reached.
e.g. given a pragma:
package MySuperPragma;
use Devel::Hints qw(ccstash);
sub import {
my ($class, %options) = @_;
my $caller = ccstash();
no strict 'refs';
*{"$caller\::whatever"} = ... ;
}
and a subclass:
package MySubPragma
use base qw(MySuperPragma);
sub import {
my ($class, %options) = @_;
$class->SUPER::import(...);
}
and a script that uses the subclass:
#!/usr/bin/env perl
use MySubPragma;
- the "ccstash" call in "MySuperPragma::import" returns the
name of the package that's being compiled when the call to
"MySuperPragma::import" (via "MySubPragma::import") takes
place i.e. "main" in this case.
fqname¶
Given a subroutine name, usually supplied by the caller of the pragma's import
method, this function returns the name in package-qualified form. In addition,
old-style "'" separators are converted to new-style "::".
If the name contains no separators, then the optional calling package is
prepended. If not supplied, the caller defaults to the value returned by
"ccstash". If the name is already package-qualified, then it is
returned unchanged.
In list context, "fqname" returns the package and unqualified
subroutine name (e.g. 'main' and 'foo'), and in scalar context it returns the
package and sub name joined by '::' (e.g. 'main::foo').
e.g.
package MyPragma;
sub import {
my ($class, @names) = @_;
for my $name (@names) {
my $fqname = fqname($name);
say $fqname;
}
}
package MySubPragma;
use base qw(MyPragma);
sub import { shift->SUPER::import(@_) }
#!/usr/bin/env perl
use MyPragma qw(foo Foo::Bar::baz Foo'Bar'baz Foo'Bar::baz);
{
package Some::Other::Package;
use MySubPragma qw(quux);
}
prints:
main::foo
Foo::Bar::baz
Foo::Bar::baz
Foo::Bar::baz
Some::Other::Package::quux
on_require¶
This function allows pragmas to register pre- and post-"require" (and
"do FILE") callbacks. These are called whenever "require"
or "do FILE" OPs are executed at compile-time, typically via
"use" statements.
"on_require" takes two callbacks (i.e. anonymous subs or sub
references), each of which is called with a reference to "%^H". The
first callback is called before "require", and the second is called
after "require" has loaded and compiled its file. %^H is cleared
before "require" and restored afterwards. (If the file has already
been loaded, or the required value is a vstring rather than a file name, then
both the callbacks and the clearance/restoration of "%^H" are
skipped.)
Multiple callbacks can be registered in a given scope, and they are called in
the order in which they are registered. Callbacks are unregistered
automatically at the end of the (compilation of) the scope in which they are
registered.
"on_require" callbacks can be used to disable/re-enable OP check hooks
installed via B::Hooks::OP::Check i.e. they can be used to make check hooks
lexically-scoped.
package MyPragma;
use Devel::Pragma qw(:all);
sub import {
my ($class, %args) = @_;
my $hints = my_hints;
unless ($hints->{MyPragma}) { # top-level
$hints->{MyPragma} = 1;
on_scope_end \&teardown;
on_require \&teardown, \&setup;
setup;
}
}
"on_require" callbacks can also be used to rollback/restore lexical
side-effects i.e. lexical features whose side-effects extend beyond
"%^H" (like "my_hints", "on_require" implicitly
renders "%^H" lexically-scoped).
Fatal exceptions raised in "on_require" callbacks are trapped and
reported as warnings. If a fatal exception is raised in the
"require" or "do FILE" call, the post-"require"
callbacks are invoked before that exception is thrown.
VERSION¶
0.54
SEE ALSO¶
- •
- pragma
- •
- perlpragma
- •
- perlvar
- •
- B::Hooks::EndOfScope
- •
- B::Hooks::OP::Check
- •
- B::Hooks::OP::PPAddr
- •
- B::Hooks::OP::Annotation
- •
- Devel::Hints
- •
- Lexical::SealRequireHints
- •
- http://tinyurl.com/45pwzo
AUTHOR¶
chocolateboy <chocolate@cpan.org>
COPYRIGHT AND LICENSE¶
Copyright (C) 2008-2010 by chocolateboy
This library is free software; you can redistribute it and/or modify it under
the same terms as Perl itself, either Perl version 5.8.1 or, at your option,
any later version of Perl 5 you may have available.