.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" 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 .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . 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 turned on, 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 .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Class::C3::Adopt::NEXT 3pm" .TH Class::C3::Adopt::NEXT 3pm "2015-06-04" "perl v5.20.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" Class::C3::Adopt::NEXT \- make NEXT suck less .SH "VERSION" .IX Header "VERSION" version 0.14 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& package MyApp::Plugin::FooBar; \& #use NEXT; \& use Class::C3::Adopt::NEXT; \& # or \*(Aquse Class::C3::Adopt::NEXT \-no_warn;\*(Aq to suppress warnings \& \& # Or use warnings::register \& # no warnings \*(AqClass::C3::Adopt::NEXT\*(Aq; \& \& # Or suppress warnings in a set of modules from one place \& # no Class::C3::Adopt::NEXT qw/ Module1 Module2 Module3 /; \& # Or suppress using a regex \& # no Class::C3::Adopt::NEXT qr/^Module\ed$/; \& \& sub a_method { \& my ($self) = @_; \& # Do some stuff \& \& # Re\-dispatch method \& # Note that this will generate a warning the _first_ time the package \& # uses NEXT unless you un comment the \*(Aqno warnings\*(Aq line above. \& $self\->NEXT::method(); \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\s-1NEXT\s0 was a good solution a few years ago, but isn't any more. It's slow, and the order in which it re-dispatches methods appears random at times. It also encourages bad programming practices, as you end up with code to re-dispatch methods when all you really wanted to do was run some code before or after a method fired. .PP However, if you have a large application, then weaning yourself off \f(CW\*(C`NEXT\*(C'\fR isn't easy. .PP This module is intended as a drop-in replacement for \s-1NEXT,\s0 supporting the same interface, but using Class::C3 to do the hard work. You can then write new code without \f(CW\*(C`NEXT\*(C'\fR, and migrate individual source files to use \f(CW\*(C`Class::C3\*(C'\fR or method modifiers as appropriate, at whatever pace you're comfortable with. .SH "WARNINGS" .IX Header "WARNINGS" This module will warn once for each package using \s-1NEXT.\s0 It uses warnings::register, and so can be disabled like by adding \f(CW\*(C`no warnings \&\*(AqClass::C3::Adopt::NEXT\*(Aq;\*(C'\fR to each package which generates a warning, or adding \&\f(CW\*(C`use Class::C3::Adopt::NEXT \-no_warn;\*(C'\fR, or disable multiple modules at once by saying: .PP .Vb 1 \& no Class::C3::Adopt::NEXT qw/ Module1 Module2 Module3 /; .Ve .PP somewhere before the warnings are first triggered. You can also setup entire name spaces of modules which will not warn using a regex, e.g. .PP .Vb 1 \& no Class::C3::Adopt::NEXT qr/^Module\ed$/; .Ve .SH "MIGRATING" .IX Header "MIGRATING" .SS "Current code using \s-1NEXT\s0" .IX Subsection "Current code using NEXT" You add \f(CW\*(C`use MRO::Compat\*(C'\fR to the top of a package as you start converting it, and gradually replace your calls to \f(CW\*(C`NEXT::method()\*(C'\fR with \&\f(CW\*(C`maybe::next::method()\*(C'\fR, and calls to \f(CW\*(C`NEXT::ACTUAL::method()\*(C'\fR with \&\f(CW\*(C`next::method()\*(C'\fR. .PP Example: .PP .Vb 2 \& sub yourmethod { \& my $self = shift; \& \& # $self\->NEXT::yourmethod(@_); becomes \& $self\->maybe::next::method(); \& } \& \& sub othermethod { \& my $self = shift; \& \& # $self\->NEXT::ACTUAL::yourmethodname(); becomes \& $self\->next::method(); \& } .Ve .PP On systems with Class::C3::XS present, this will automatically be used to speed up method re-dispatch. If you are running perl version 5.9.5 or greater then the C3 method resolution algorithm is included in perl. Correct use of MRO::Compat as shown above allows your code to be seamlessly forward and backwards compatible, taking advantage of native versions if available, but falling back to using pure perl \f(CW\*(C`Class::C3\*(C'\fR. .SS "Writing new code" .IX Subsection "Writing new code" Use Moose and make all of your plugins Moose::Roles, then use method modifiers to wrap methods. .PP Example: .PP .Vb 2 \& package MyApp::Role::FooBar; \& use Moose::Role; \& \& before \*(Aqa_method\*(Aq => sub { \& my ($self) = @_; \& # Do some stuff \& }; \& \& around \*(Aqa_method\*(Aq => sub { \& my $orig = shift; \& my $self = shift; \& # Do some stuff before \& my $ret = $self\->$orig(@_); # Run wrapped method (or not!) \& # Do some stuff after \& return $ret; \& }; \& \& package MyApp; \& use Moose; \& \& with \*(AqMyApp::Role::FooBar\*(Aq; .Ve .SH "CAVEATS" .IX Header "CAVEATS" There are some inheritance hierarchies that it is possible to create which cannot be resolved to a simple C3 hierarchy. In that case, this module will fall back to using \f(CW\*(C`NEXT\*(C'\fR. In this case a warning will be emitted. .PP Because calculating the method resolution order of every class every time \f(CW\*(C`\->NEXT::foo\*(C'\fR is used from within it is too expensive, runtime manipulations of \f(CW@ISA\fR are prohibited. .SH "FUNCTIONS" .IX Header "FUNCTIONS" This module replaces \f(CW\*(C`NEXT::AUTOLOAD\*(C'\fR with its own version. If warnings are enabled then a warning will be emitted on the first use of \f(CW\*(C`NEXT\*(C'\fR by each package. .SH "SEE ALSO" .IX Header "SEE ALSO" MRO::Compat and Class::C3 for method re-dispatch and Moose for method modifiers and roles. .PP \&\s-1NEXT\s0 for documentation on the functionality you'll be removing. .SH "AUTHORS" .IX Header "AUTHORS" .IP "\(bu" 4 Florian Ragwitz .IP "\(bu" 4 Tomas Doran .SH "CONTRIBUTOR" .IX Header "CONTRIBUTOR" Karen Etheridge .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2015 by Florian Ragwitz. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.