summaryrefslogtreecommitdiffstats
path: root/upstream/mageia-cauldron/man1/perlpragma.1
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/mageia-cauldron/man1/perlpragma.1')
-rw-r--r--upstream/mageia-cauldron/man1/perlpragma.1230
1 files changed, 230 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man1/perlpragma.1 b/upstream/mageia-cauldron/man1/perlpragma.1
new file mode 100644
index 00000000..bc9afc5f
--- /dev/null
+++ b/upstream/mageia-cauldron/man1/perlpragma.1
@@ -0,0 +1,230 @@
+.\" -*- 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 "PERLPRAGMA 1"
+.TH PERLPRAGMA 1 2023-11-28 "perl v5.38.2" "Perl Programmers Reference Guide"
+.\" 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
+perlpragma \- how to write a user pragma
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+A pragma is a module which influences some aspect of the compile time or run
+time behaviour of Perl, such as \f(CW\*(C`strict\*(C'\fR or \f(CW\*(C`warnings\*(C'\fR. With Perl 5.10 you
+are no longer limited to the built in pragmata; you can now create user
+pragmata that modify the behaviour of user functions within a lexical scope.
+.SH "A basic example"
+.IX Header "A basic example"
+For example, say you need to create a class implementing overloaded
+mathematical operators, and would like to provide your own pragma that
+functions much like \f(CW\*(C`use integer;\*(C'\fR You'd like this code
+.PP
+.Vb 1
+\& use MyMaths;
+\&
+\& my $l = MyMaths\->new(1.2);
+\& my $r = MyMaths\->new(3.4);
+\&
+\& print "A: ", $l + $r, "\en";
+\&
+\& use myint;
+\& print "B: ", $l + $r, "\en";
+\&
+\& {
+\& no myint;
+\& print "C: ", $l + $r, "\en";
+\& }
+\&
+\& print "D: ", $l + $r, "\en";
+\&
+\& no myint;
+\& print "E: ", $l + $r, "\en";
+.Ve
+.PP
+to give the output
+.PP
+.Vb 5
+\& A: 4.6
+\& B: 4
+\& C: 4.6
+\& D: 4
+\& E: 4.6
+.Ve
+.PP
+\&\fIi.e.\fR, where \f(CW\*(C`use myint;\*(C'\fR is in effect, addition operations are forced
+to integer, whereas by default they are not, with the default behaviour being
+restored via \f(CW\*(C`no myint;\*(C'\fR
+.PP
+The minimal implementation of the package \f(CW\*(C`MyMaths\*(C'\fR would be something like
+this:
+.PP
+.Vb 12
+\& package MyMaths;
+\& use v5.36;
+\& use myint();
+\& use overload \*(Aq+\*(Aq => sub {
+\& my ($l, $r) = @_;
+\& # Pass 1 to check up one call level from here
+\& if (myint::in_effect(1)) {
+\& int($$l) + int($$r);
+\& } else {
+\& $$l + $$r;
+\& }
+\& };
+\&
+\& sub new {
+\& my ($class, $value) = @_;
+\& bless \e$value, $class;
+\& }
+\&
+\& 1;
+.Ve
+.PP
+Note how we load the user pragma \f(CW\*(C`myint\*(C'\fR with an empty list \f(CW\*(C`()\*(C'\fR to
+prevent its \f(CW\*(C`import\*(C'\fR being called.
+.PP
+The interaction with the Perl compilation happens inside package \f(CW\*(C`myint\*(C'\fR:
+.PP
+.Vb 1
+\& package myint;
+\&
+\& use v5.36;
+\&
+\& sub import {
+\& $^H{"myint/in_effect"} = 1;
+\& }
+\&
+\& sub unimport {
+\& $^H{"myint/in_effect"} = 0;
+\& }
+\&
+\& sub in_effect {
+\& my $level = shift // 0;
+\& my $hinthash = (caller($level))[10];
+\& return $hinthash\->{"myint/in_effect"};
+\& }
+\&
+\& 1;
+.Ve
+.PP
+As pragmata are implemented as modules, like any other module, \f(CW\*(C`use myint;\*(C'\fR
+becomes
+.PP
+.Vb 4
+\& BEGIN {
+\& require myint;
+\& myint\->import();
+\& }
+.Ve
+.PP
+and \f(CW\*(C`no myint;\*(C'\fR is
+.PP
+.Vb 4
+\& BEGIN {
+\& require myint;
+\& myint\->unimport();
+\& }
+.Ve
+.PP
+Hence the \f(CW\*(C`import\*(C'\fR and \f(CW\*(C`unimport\*(C'\fR routines are called at \fBcompile time\fR
+for the user's code.
+.PP
+User pragmata store their state by writing to the magical hash \f(CW\*(C`%^H\*(C'\fR,
+hence these two routines manipulate it. The state information in \f(CW\*(C`%^H\*(C'\fR is
+stored in the optree, and can be retrieved read-only at runtime with \f(CWcaller()\fR,
+at index 10 of the list of returned results. In the example pragma, retrieval
+is encapsulated into the routine \f(CWin_effect()\fR, which takes as parameter
+the number of call frames to go up to find the value of the pragma in the
+user's script. This uses \f(CWcaller()\fR to determine the value of
+\&\f(CW$^H{"myint/in_effect"}\fR when each line of the user's script was called, and
+therefore provide the correct semantics in the subroutine implementing the
+overloaded addition.
+.SH "Key naming"
+.IX Header "Key naming"
+There is only a single \f(CW\*(C`%^H\*(C'\fR, but arbitrarily many modules that want
+to use its scoping semantics. To avoid stepping on each other's toes,
+they need to be sure to use different keys in the hash. It is therefore
+conventional for a module to use only keys that begin with the module's
+name (the name of its main package) and a "/" character. After this
+module-identifying prefix, the rest of the key is entirely up to the
+module: it may include any characters whatsoever. For example, a module
+\&\f(CW\*(C`Foo::Bar\*(C'\fR should use keys such as \f(CW\*(C`Foo::Bar/baz\*(C'\fR and \f(CW\*(C`Foo::Bar/$%/_!\*(C'\fR.
+Modules following this convention all play nicely with each other.
+.PP
+The Perl core uses a handful of keys in \f(CW\*(C`%^H\*(C'\fR which do not follow this
+convention, because they predate it. Keys that follow the convention
+won't conflict with the core's historical keys.
+.SH "Implementation details"
+.IX Header "Implementation details"
+The optree is shared between threads. This means there is a possibility that
+the optree will outlive the particular thread (and therefore the interpreter
+instance) that created it, so true Perl scalars cannot be stored in the
+optree. Instead a compact form is used, which can only store values that are
+integers (signed and unsigned), strings or \f(CW\*(C`undef\*(C'\fR \- references and
+floating point values are stringified. If you need to store multiple values
+or complex structures, you should serialise them, for example with \f(CW\*(C`pack\*(C'\fR.
+The deletion of a hash key from \f(CW\*(C`%^H\*(C'\fR is recorded, and as ever can be
+distinguished from the existence of a key with value \f(CW\*(C`undef\*(C'\fR with
+\&\f(CW\*(C`exists\*(C'\fR.
+.PP
+\&\fBDon't\fR attempt to store references to data structures as integers which
+are retrieved via \f(CW\*(C`caller\*(C'\fR and converted back, as this will not be threadsafe.
+Accesses would be to the structure without locking (which is not safe for
+Perl's scalars), and either the structure has to leak, or it has to be
+freed when its creating thread terminates, which may be before the optree
+referencing it is deleted, if other threads outlive it.