diff options
Diffstat (limited to 'upstream/mageia-cauldron/man1/perlpragma.1')
-rw-r--r-- | upstream/mageia-cauldron/man1/perlpragma.1 | 230 |
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. |