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 = hints; # lexically-scoped %^H
my $caller = ccstash(); # currently-compiling stash
unless ($hints->{MyPragma}) { # top-level
$hints->{MyPragma} = 1;
}
if (new_scope($class)) {
...
}
my $scope_id = scope();
}
DESCRIPTION
This module provides helper functions for developers of lexical pragmas, though a few functions may be useful to non-pragma developers as well.
Pragmas can be used both in older versions of perl (from 5.8.1), which had limited support, 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);
hints
This function enables the scoped behaviour of the hints hash (%^H
) and then returns a reference to it.
The hints hash is a compile-time global variable (which is also available at runtime in recent perls) that can be used to implement lexically-scoped features and pragmas. This function provides a convenient way to access this hash without the need to perform the bit-twiddling that enables it on older perls. In addition, this module loads Lexical::SealRequireHints, which implements bugfixes that are required for the correct operation of the hints hash on older perls (< 5.12.0).
Typically, hints
should be called from a pragma's import
(and optionally unimport
) method:
package MyPragma;
use Devel::Pragma qw(hints);
sub import {
my $class = shift;
my $hints = hints;
if ($hints->{MyPragma}) {
# ...
} else {
$hints->{MyPragma} = ...;
}
# ...
}
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 "hints".
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
VERSION
1.0.1
SEE ALSO
http://tinyurl.com/45pwzo
AUTHOR
chocolateboy <chocolate@cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2008-2016 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.