.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Devel::Pragma 3pm" .TH Devel::Pragma 3pm 2024-03-07 "perl v5.38.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Devel::Pragma \- helper functions for developers of lexical pragmas .SH SYNOPSIS .IX Header "SYNOPSIS" .Vb 1 \& package MyPragma; \& \& use Devel::Pragma qw(:all); \& \& sub import { \& my ($class, %options) = @_; \& my $hints = hints; # the builtin (%^H) used to implement lexical pragmas \& my $caller = ccstash(); # the name of the currently\-compiling package (stash) \& \& unless ($hints\->{MyPragma}) { # top\-level \& $hints\->{MyPragma} = 1; \& } \& \& if (new_scope($class)) { \& ... \& } \& \& my $scope_id = scope(); \& } .Ve .SH DESCRIPTION .IX Header "DESCRIPTION" This module provides helper functions for developers of lexical pragmas (and a few functions that may be useful to non-pragma developers as well). .PP 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. .SH EXPORTS .IX Header "EXPORTS" \&\f(CW\*(C`Devel::Pragma\*(C'\fR exports the following functions on demand. They can all be imported at once by using the \f(CW\*(C`:all\*(C'\fR tag. e.g. .PP .Vb 1 \& use Devel::Pragma qw(:all); .Ve .SS hints .IX Subsection "hints" This function enables the scoped behaviour of the hints hash (\f(CW\*(C`%^H\*(C'\fR) and then returns a reference to it. .PP 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). .PP Typically, \f(CW\*(C`hints\*(C'\fR should be called from a pragma's \f(CW\*(C`import\*(C'\fR (and optionally \f(CW\*(C`unimport\*(C'\fR) method: .PP .Vb 1 \& package MyPragma; \& \& use Devel::Pragma qw(hints); \& \& sub import { \& my $class = shift; \& my $hints = hints; \& \& if ($hints\->{MyPragma}) { \& # ... \& } else { \& $hints\->{MyPragma} = ...; \& } \& \& # ... \& } .Ve .SS new_scope .IX Subsection "new_scope" This function returns true if the currently-compiling scope differs from the scope being compiled the last time \f(CW\*(C`new_scope\*(C'\fR was called. Subsequent calls will return false while the same scope is being compiled. .PP \&\f(CW\*(C`new_scope\*(C'\fR takes an optional parameter that is used to uniquely identify its caller. This should usually be supplied as the pragma's class name unless \f(CW\*(C`new_scope\*(C'\fR is called by a module that is not intended to be subclassed. e.g. .PP .Vb 1 \& package MyPragma; \& \& sub import { \& my ($class, %options) = @_; \& \& if (new_scope($class)) { \& ... \& } \& } .Ve .PP If not supplied, the identifier defaults to the name of the calling package. .SS scope .IX Subsection "scope" This returns an integer that uniquely identifies the currently-compiling scope. It can be used to distinguish or compare scopes. .PP A warning is issued if \f(CW\*(C`scope\*(C'\fR (or \f(CW\*(C`new_scope\*(C'\fR) is called in a context in which it doesn't make sense i.e. if the scoped behaviour of \f(CW\*(C`%^H\*(C'\fR has not been enabled \- either by explicitly modifying \f(CW$^H\fR, or by calling "hints". .SS ccstash .IX Subsection "ccstash" Returns the name of the currently-compiling package (stash). It only works inside code that's being \f(CW\*(C`required\*(C'\fR, either in a BEGIN block via \f(CW\*(C`use\*(C'\fR or at runtime. In practice, its use should be restricted to compile-time i.e. \&\f(CW\*(C`import\*(C'\fR methods and any other methods/functions that can be traced back to \f(CW\*(C`import\*(C'\fR. .PP When called from code that isn't being \f(CW\*(C`require\*(C'\fRd, it returns undef. .PP It can be used as a replacement for the scalar form of \f(CW\*(C`caller\*(C'\fR to provide the name of the package in which \&\f(CW\*(C`use MyPragma\*(C'\fR is called. Unlike \f(CW\*(C`caller\*(C'\fR, it returns the same value regardless of the number of intervening calls before \f(CW\*(C`MyPragma::import\*(C'\fR is reached. .PP .Vb 1 \& package Caller; \& \& use Callee; \& \& package Callee; \& \& use Devel::Pragma qw(ccstash); \& \& sub import { \& A(); \& } \& \& sub A() { \& B(); \& } \& \& sub B { \& C(); \& } \& \& sub C { \& say ccstash; # Caller \& } .Ve .SS fqname .IX Subsection "fqname" Takes a subroutine name and an optional caller (package name). If no caller is supplied, it defaults to "ccstash", which requires \f(CW\*(C`fqname\*(C'\fR to be called from \f(CW\*(C`import\*(C'\fR (or a function/method that can be traced back to \f(CW\*(C`import\*(C'\fR). .PP It returns the supplied name in package-qualified form. In addition, old-style \f(CW\*(C`\*(Aq\*(C'\fR separators are converted to new-style \f(CW\*(C`::\*(C'\fR. .PP If the name contains no separators, then the \f(CW\*(C`caller\*(C'\fR/\f(CW\*(C`ccstash\*(C'\fR package name is prepended. If the name is already package-qualified, it is returned unchanged. .PP In list context, \f(CW\*(C`fqname\*(C'\fR returns the package and unqualified subroutine name (e.g. 'Foo::Bar' and 'baz'), and in scalar context it returns the package and sub name joined by '::' (e.g. 'Foo::Bar::baz'). .PP e.g. .PP .Vb 1 \& package MyPragma::Loader; \& \& use MyPragma (\e&coderef, \*(Aqfoo\*(Aq, \*(AqMyPragmaLoader::bar\*(Aq); \& \& package MyPragma; \& \& sub import { \& my ($class, @listeners) = @_; \& my @subs; \& \& for my $listener (@listeners) { \& push @subs, handle_sub($listener); \& } \& } \& \& sub handle_sub { \& my $sub = shift \& \& if (ref($ub) eq \*(AqCODE\*(Aq) { \& return $sub; \& } else { \& handle_name($sub); \& } \& } \& \& sub handle_name { \& my ($package, $name) = fqname($name); # uses ccstash e.g. foo \-> MyPragma::Loader::foo \& my $sub = $package\->can($name); \& die "no such sub: $package\e::$name" unless ($sub); \& return $sub; \& } .Ve .SH VERSION .IX Header "VERSION" 1.1.0 .SH "SEE ALSO" .IX Header "SEE ALSO" .IP \(bu 4 Devel::Hints .IP \(bu 4 Lexical::Hints .IP \(bu 4 Lexical::SealRequireHints .IP \(bu 4 perlpragma .IP \(bu 4 pragma .IP \(bu 4 http://tinyurl.com/45pwzo .SH AUTHOR .IX Header "AUTHOR" chocolateboy .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" Copyright (C) 2008\-2016 by chocolateboy .PP 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.