diff options
Diffstat (limited to 'upstream/mageia-cauldron/man3pm/mro.3pm')
-rw-r--r-- | upstream/mageia-cauldron/man3pm/mro.3pm | 325 |
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 |