summaryrefslogtreecommitdiffstats
path: root/upstream/mageia-cauldron/man3pm/mro.3pm
diff options
context:
space:
mode:
Diffstat (limited to 'upstream/mageia-cauldron/man3pm/mro.3pm')
-rw-r--r--upstream/mageia-cauldron/man3pm/mro.3pm325
1 files changed, 325 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man3pm/mro.3pm b/upstream/mageia-cauldron/man3pm/mro.3pm
new file mode 100644
index 00000000..3f0bd8f1
--- /dev/null
+++ b/upstream/mageia-cauldron/man3pm/mro.3pm
@@ -0,0 +1,325 @@
+.\" -*- 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 "mro 3pm"
+.TH mro 3pm 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
+mro \- Method Resolution Order
+.SH SYNOPSIS
+.IX Header "SYNOPSIS"
+.Vb 1
+\& use mro; # enables next::method and friends globally
+\&
+\& use mro \*(Aqdfs\*(Aq; # enable DFS MRO for this class (Perl default)
+\& use mro \*(Aqc3\*(Aq; # enable C3 MRO for this class
+.Ve
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+The "mro" namespace provides several utilities for dealing
+with method resolution order and method caching in general.
+.PP
+These interfaces are only available in Perl 5.9.5 and higher.
+See MRO::Compat on CPAN for a mostly forwards compatible
+implementation for older Perls.
+.SH OVERVIEW
+.IX Header "OVERVIEW"
+It's possible to change the MRO of a given class either by using \f(CW\*(C`use
+mro\*(C'\fR as shown in the synopsis, or by using the "mro::set_mro" function
+below.
+.PP
+The special methods \f(CW\*(C`next::method\*(C'\fR, \f(CW\*(C`next::can\*(C'\fR, and
+\&\f(CW\*(C`maybe::next::method\*(C'\fR are not available until this \f(CW\*(C`mro\*(C'\fR module
+has been loaded via \f(CW\*(C`use\*(C'\fR or \f(CW\*(C`require\*(C'\fR.
+.SH "The C3 MRO"
+.IX Header "The C3 MRO"
+In addition to the traditional Perl default MRO (depth first
+search, called \f(CW\*(C`DFS\*(C'\fR here), Perl now offers the C3 MRO as
+well. Perl's support for C3 is based on the work done in
+Stevan Little's module Class::C3, and most of the C3\-related
+documentation here is ripped directly from there.
+.SS "What is C3?"
+.IX Subsection "What is C3?"
+C3 is the name of an algorithm which aims to provide a sane method
+resolution order under multiple inheritance. It was first introduced in
+the language Dylan (see links in the "SEE ALSO" section), and then
+later adopted as the preferred MRO (Method Resolution Order) for the
+new-style classes in Python 2.3. Most recently it has been adopted as the
+"canonical" MRO for Raku classes.
+.SS "How does C3 work"
+.IX Subsection "How does C3 work"
+C3 works by always preserving local precedence ordering. This essentially
+means that no class will appear before any of its subclasses. Take, for
+instance, the classic diamond inheritance pattern:
+.PP
+.Vb 5
+\& <A>
+\& / \e
+\& <B> <C>
+\& \e /
+\& <D>
+.Ve
+.PP
+The standard Perl 5 MRO would be (D, B, A, C). The result being that \fBA\fR
+appears before \fBC\fR, even though \fBC\fR is the subclass of \fBA\fR. The C3 MRO
+algorithm however, produces the following order: (D, B, C, A), which does
+not have this issue.
+.PP
+This example is fairly trivial; for more complex cases and a deeper
+explanation, see the links in the "SEE ALSO" section.
+.SH Functions
+.IX Header "Functions"
+.ie n .SS "mro::get_linear_isa($classname[, $type])"
+.el .SS "mro::get_linear_isa($classname[, \f(CW$type\fP])"
+.IX Subsection "mro::get_linear_isa($classname[, $type])"
+Returns an arrayref which is the linearized MRO of the given class.
+Uses whichever MRO is currently in effect for that class by default,
+or the given MRO (either \f(CW\*(C`c3\*(C'\fR or \f(CW\*(C`dfs\*(C'\fR if specified as \f(CW$type\fR).
+.PP
+The linearized MRO of a class is an ordered array of all of the
+classes one would search when resolving a method on that class,
+starting with the class itself.
+.PP
+If the requested class doesn't yet exist, this function will still
+succeed, and return \f(CW\*(C`[ $classname ]\*(C'\fR
+.PP
+Note that \f(CW\*(C`UNIVERSAL\*(C'\fR (and any members of \f(CW\*(C`UNIVERSAL\*(C'\fR's MRO) are not
+part of the MRO of a class, even though all classes implicitly inherit
+methods from \f(CW\*(C`UNIVERSAL\*(C'\fR and its parents.
+.ie n .SS "mro::set_mro ($classname, $type)"
+.el .SS "mro::set_mro ($classname, \f(CW$type\fP)"
+.IX Subsection "mro::set_mro ($classname, $type)"
+Sets the MRO of the given class to the \f(CW$type\fR argument (either
+\&\f(CW\*(C`c3\*(C'\fR or \f(CW\*(C`dfs\*(C'\fR).
+.SS mro::get_mro($classname)
+.IX Subsection "mro::get_mro($classname)"
+Returns the MRO of the given class (either \f(CW\*(C`c3\*(C'\fR or \f(CW\*(C`dfs\*(C'\fR).
+.SS mro::get_isarev($classname)
+.IX Subsection "mro::get_isarev($classname)"
+Gets the \f(CW\*(C`mro_isarev\*(C'\fR for this class, returned as an
+arrayref of class names. These are every class that "isa"
+the given class name, even if the isa relationship is
+indirect. This is used internally by the MRO code to
+keep track of method/MRO cache invalidations.
+.PP
+As with \f(CW\*(C`mro::get_linear_isa\*(C'\fR above, \f(CW\*(C`UNIVERSAL\*(C'\fR is special.
+\&\f(CW\*(C`UNIVERSAL\*(C'\fR (and parents') isarev lists do not include
+every class in existence, even though all classes are
+effectively descendants for method inheritance purposes.
+.SS mro::is_universal($classname)
+.IX Subsection "mro::is_universal($classname)"
+Returns a boolean status indicating whether or not
+the given classname is either \f(CW\*(C`UNIVERSAL\*(C'\fR itself,
+or one of \f(CW\*(C`UNIVERSAL\*(C'\fR's parents by \f(CW@ISA\fR inheritance.
+.PP
+Any class for which this function returns true is
+"universal" in the sense that all classes potentially
+inherit methods from it.
+.SS \fBmro::invalidate_all_method_caches()\fP
+.IX Subsection "mro::invalidate_all_method_caches()"
+Increments \f(CW\*(C`PL_sub_generation\*(C'\fR, which invalidates method
+caching in all packages.
+.SS mro::method_changed_in($classname)
+.IX Subsection "mro::method_changed_in($classname)"
+Invalidates the method cache of any classes dependent on the
+given class. This is not normally necessary. The only
+known case where pure perl code can confuse the method
+cache is when you manually install a new constant
+subroutine by using a readonly scalar value, like the
+internals of constant do. If you find another case,
+please report it so we can either fix it or document
+the exception here.
+.SS mro::get_pkg_gen($classname)
+.IX Subsection "mro::get_pkg_gen($classname)"
+Returns an integer which is incremented every time a
+real local method in the package \f(CW$classname\fR changes,
+or the local \f(CW@ISA\fR of \f(CW$classname\fR is modified.
+.PP
+This is intended for authors of modules which do lots
+of class introspection, as it allows them to very quickly
+check if anything important about the local properties
+of a given class have changed since the last time they
+looked. It does not increment on method/\f(CW@ISA\fR
+changes in superclasses.
+.PP
+It's still up to you to seek out the actual changes,
+and there might not actually be any. Perhaps all
+of the changes since you last checked cancelled each
+other out and left the package in the state it was in
+before.
+.PP
+This integer normally starts off at a value of \f(CW1\fR
+when a package stash is instantiated. Calling it
+on packages whose stashes do not exist at all will
+return \f(CW0\fR. If a package stash is completely
+deleted (not a normal occurrence, but it can happen
+if someone does something like \f(CW\*(C`undef %PkgName::\*(C'\fR),
+the number will be reset to either \f(CW0\fR or \f(CW1\fR,
+depending on how completely the package was wiped out.
+.SS next::method
+.IX Subsection "next::method"
+This is somewhat like \f(CW\*(C`SUPER\*(C'\fR, but it uses the C3 method
+resolution order to get better consistency in multiple
+inheritance situations. Note that while inheritance in
+general follows whichever MRO is in effect for the
+given class, \f(CW\*(C`next::method\*(C'\fR only uses the C3 MRO.
+.PP
+One generally uses it like so:
+.PP
+.Vb 5
+\& sub some_method {
+\& my $self = shift;
+\& my $superclass_answer = $self\->next::method(@_);
+\& return $superclass_answer + 1;
+\& }
+.Ve
+.PP
+Note that you don't (re\-)specify the method name.
+It forces you to always use the same method name
+as the method you started in.
+.PP
+It can be called on an object or a class, of course.
+.PP
+The way it resolves which actual method to call is:
+.IP 1. 4
+First, it determines the linearized C3 MRO of
+the object or class it is being called on.
+.IP 2. 4
+Then, it determines the class and method name
+of the context it was invoked from.
+.IP 3. 4
+Finally, it searches down the C3 MRO list until
+it reaches the contextually enclosing class, then
+searches further down the MRO list for the next
+method with the same name as the contextually
+enclosing method.
+.PP
+Failure to find a next method will result in an
+exception being thrown (see below for alternatives).
+.PP
+This is substantially different than the behavior
+of \f(CW\*(C`SUPER\*(C'\fR under complex multiple inheritance.
+(This becomes obvious when one realizes that the
+common superclasses in the C3 linearizations of
+a given class and one of its parents will not
+always be ordered the same for both.)
+.PP
+\&\fBCaveat\fR: Calling \f(CW\*(C`next::method\*(C'\fR from methods defined outside the class:
+.PP
+There is an edge case when using \f(CW\*(C`next::method\*(C'\fR from within a subroutine
+which was created in a different module than the one it is called from. It
+sounds complicated, but it really isn't. Here is an example which will not
+work correctly:
+.PP
+.Vb 1
+\& *Foo::foo = sub { (shift)\->next::method(@_) };
+.Ve
+.PP
+The problem exists because the anonymous subroutine being assigned to the
+\&\f(CW*Foo::foo\fR glob will show up in the call stack as being called
+\&\f(CW\*(C`_\|_ANON_\|_\*(C'\fR and not \f(CW\*(C`foo\*(C'\fR as you might expect. Since \f(CW\*(C`next::method\*(C'\fR uses
+\&\f(CW\*(C`caller\*(C'\fR to find the name of the method it was called in, it will fail in
+this case.
+.PP
+But fear not, there's a simple solution. The module \f(CW\*(C`Sub::Name\*(C'\fR will
+reach into the perl internals and assign a name to an anonymous subroutine
+for you. Simply do this:
+.PP
+.Vb 2
+\& use Sub::Name \*(Aqsubname\*(Aq;
+\& *Foo::foo = subname \*(AqFoo::foo\*(Aq => sub { (shift)\->next::method(@_) };
+.Ve
+.PP
+and things will Just Work.
+.SS next::can
+.IX Subsection "next::can"
+This is similar to \f(CW\*(C`next::method\*(C'\fR, but just returns either a code
+reference or \f(CW\*(C`undef\*(C'\fR to indicate that no further methods of this name
+exist.
+.SS maybe::next::method
+.IX Subsection "maybe::next::method"
+In simple cases, it is equivalent to:
+.PP
+.Vb 1
+\& $self\->next::method(@_) if $self\->next::can;
+.Ve
+.PP
+But there are some cases where only this solution
+works (like \f(CW\*(C`goto &maybe::next::method\*(C'\fR);
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+.SS "The original Dylan paper"
+.IX Subsection "The original Dylan paper"
+.IP <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.19.3910&rep=rep1&type=pdf> 4
+.IX Item "<http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.19.3910&rep=rep1&type=pdf>"
+.SS "Python 2.3 MRO"
+.IX Subsection "Python 2.3 MRO"
+.PD 0
+.IP <https://www.python.org/download/releases/2.3/mro/> 4
+.IX Item "<https://www.python.org/download/releases/2.3/mro/>"
+.PD
+.SS Class::C3
+.IX Subsection "Class::C3"
+.IP Class::C3 4
+.IX Item "Class::C3"
+.SH AUTHOR
+.IX Header "AUTHOR"
+Brandon L. Black, <blblack@gmail.com>
+.PP
+Based on Stevan Little's Class::C3