argra****@users*****
argra****@users*****
2008年 6月 19日 (木) 01:24:49 JST
Index: docs/modules/mro-1.00/mro.pod diff -u /dev/null docs/modules/mro-1.00/mro.pod:1.1 --- /dev/null Thu Jun 19 01:24:49 2008 +++ docs/modules/mro-1.00/mro.pod Thu Jun 19 01:24:49 2008 @@ -0,0 +1,771 @@ + +=encoding euc-jp + +=head1 NAME + +=begin original + +mro - Method Resolution Order + +=end original + +mro - メソッド解決順序(Method Resolution Order) + +=head1 SYNOPSIS + + use mro; # enables next::method and friends globally + + use mro 'dfs'; # enable DFS MRO for this class (Perl default) + use mro 'c3'; # enable C3 MRO for this class + +=head1 DESCRIPTION + +=begin original + +The "mro" namespace provides several utilities for dealing +with method resolution order and method caching in general. + +=end original + +"mro" 名前空間はメソッド解決順序と一般的なメソッドキャッシュを扱うための +いくつかのユーティリティを提供します。 + +=begin original + +These interfaces are only available in Perl 5.9.5 and higher. +See L<MRO::Compat> on CPAN for a mostly forwards compatible +implementation for older Perls. + +=end original + +これらのインターフェースは Perl 5.9.5 以上でのみ利用可能です。 +より古い Perl でのほとんど前方互換実装については CPAN の L<MRO::Compat> を +参照してください。 + +=head1 OVERVIEW + +(概観) + +=begin original + +It's possible to change the MRO of a given class either by using C<use +mro> as shown in the synopsis, or by using the L</mro::set_mro> function +below. The functions in the mro namespace do not require loading the +C<mro> module, as they are actually provided by the core perl interpreter. + +=end original + +あるクラスでの MRO は、上述の C<use mro> を使うか、以下の L</mro::set_mro> +関数を使うことで変更できます。 +mro 名前空間の関数は C<mro> モジュールを読み込む必要はなく、実際には +コア perl インタプリタによって提供されます。 + +=begin original + +The special methods C<next::method>, C<next::can>, and +C<maybe::next::method> are not available until this C<mro> module +has been loaded via C<use> or C<require>. + +=end original + +特殊メソッド C<next::method>, C<next::can>, C<maybe::next::method> は +C<use> か C<require> によって C<mro> モジュールを読み込むまで +利用できません。 + +=head1 The C3 MRO + +=begin original + +In addition to the traditional Perl default MRO (depth first +search, called C<DFS> 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 L<Class::C3>, and most of the C3-related +documentation here is ripped directly from there. + +=end original + +伝統的な Perl のデフォルトの MRO (深さ優先探索; ここでは C<DFS> と +呼ばれます)にくわえて、Perl は C3 MRO も提供するようになりました。 +Perl の C3 対応は Stevan Little による L<Class::C3> モジュールで行われた +作業を基としていて、ここにある C3 関係の文章のほとんどは、そこから直接 +コピーされたものです。 + +=head2 What is C3? + +(C3 って何?) + +=begin original + +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 L</"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 Perl 6 classes, and the default MRO for Parrot objects +as well. + +=end original + +C3 は多重継承における健全なメソッド解決順序を提供することを目的とした +アルゴリズムの名前です。 +これは最初に Dylan と言う言語 (L</"SEE ALSO"> の章のリンクを +参照してください)、で導入され、後に Python 2.3 の新型のクラスでの +優先 MRO (Method Resolution Order; メソッド解決順序) として採用されました。 +つい最近では Perl 6 のクラスでの「正統な」MRO として採用され、Parrot +プロジェクトでもデフォルトの MRO として採用されました。 + +=head2 How does C3 work + +(C3 の動作) + +=begin original + +C3 works by always preserving local precendence ordering. This essentially +means that no class will appear before any of its subclasses. Take, for +instance, the classic diamond inheritance pattern: + +=end original + +C3 は常に局所的な優先順位を保存して動作します。 +これは、基本的にどのクラスもそのサブクラスより先に現れることはないことを +意味します。 +例えば、以下のような古典的なダイヤ型継承パターンを考えます: + + <A> + / \ + <B> <C> + \ / + <D> + +=begin original + +The standard Perl 5 MRO would be (D, B, A, C). The result being that B<A> +appears before B<C>, even though B<C> is the subclass of B<A>. The C3 MRO +algorithm however, produces the following order: (D, B, C, A), which does +not have this issue. + +=end original + +標準の Perl 5 MRO は (D, B, A, C) です。 +この結果、B<C> は B<A> のサブクラスにも関わらず、B<A> が B<C> より先に +検索されます。 +しかし、C3 MRO アルゴリズムでは、(D, B, C, A) の順序になり、この問題は +ありません。 + +=begin original + +This example is fairly trivial; for more complex cases and a deeper +explanation, see the links in the L</"SEE ALSO"> section. + +=end original + +この例はかなりつまらないものです; より複雑な場合とより深い説明については、 +L</"SEE ALSO"> の章のリンクを参照してください。 + +=head1 Functions + +=head2 mro::get_linear_isa($classname[, $type]) + +=begin original + +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 C<c3> or C<dfs> if specified as C<$type>). + +=end original + +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 C<c3> or C<dfs> if specified as C<$type>). +(TBT) + +=begin original + +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. + +=end original + +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. +(TBT) + +=begin original + +If the requested class doesn't yet exist, this function will still +succeed, and return C<[ $classname ]> + +=end original + +If the requested class doesn't yet exist, this function will still +succeed, and return C<[ $classname ]> +(TBT) + +=begin original + +Note that C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not +part of the MRO of a class, even though all classes implicitly inherit +methods from C<UNIVERSAL> and its parents. + +=end original + +Note that C<UNIVERSAL> (and any members of C<UNIVERSAL>'s MRO) are not +part of the MRO of a class, even though all classes implicitly inherit +methods from C<UNIVERSAL> and its parents. +(TBT) + +=head2 mro::set_mro($classname, $type) + +=begin original + +Sets the MRO of the given class to the C<$type> argument (either +C<c3> or C<dfs>). + +=end original + +Sets the MRO of the given class to the C<$type> argument (either +C<c3> or C<dfs>). +(TBT) + +=head2 mro::get_mro($classname) + +=begin original + +Returns the MRO of the given class (either C<c3> or C<dfs>). + +=end original + +Returns the MRO of the given class (either C<c3> or C<dfs>). +(TBT) + +=head2 mro::get_isarev($classname) + +=begin original + +Gets the C<mro_isarev> 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. + +=end original + +Gets the C<mro_isarev> 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. +(TBT) + +=begin original + +Currently, this list only grows, it never shrinks. This +was a performance consideration (properly tracking and +deleting isarev entries when someone removes an entry +from an C<@ISA> is costly, and it doesn't happen often +anyways). The fact that a class which no longer truly +"isa" this class at runtime remains on the list should be +considered a quirky implementation detail which is subject +to future change. It shouldn't be an issue as long as +you're looking at this list for the same reasons the +core code does: as a performance optimization +over having to search every class in existence. + +=end original + +Currently, this list only grows, it never shrinks. This +was a performance consideration (properly tracking and +deleting isarev entries when someone removes an entry +from an C<@ISA> is costly, and it doesn't happen often +anyways). The fact that a class which no longer truly +"isa" this class at runtime remains on the list should be +considered a quirky implementation detail which is subject +to future change. It shouldn't be an issue as long as +you're looking at this list for the same reasons the +core code does: as a performance optimization +over having to search every class in existence. +(TBT) + +=begin original + +As with C<mro::get_mro> above, C<UNIVERSAL> is special. +C<UNIVERSAL> (and parents') isarev lists do not include +every class in existence, even though all classes are +effectively descendants for method inheritance purposes. + +=end original + +As with C<mro::get_mro> above, C<UNIVERSAL> is special. +C<UNIVERSAL> (and parents') isarev lists do not include +every class in existence, even though all classes are +effectively descendants for method inheritance purposes. +(TBT) + +=head2 mro::is_universal($classname) + +=begin original + +Returns a boolean status indicating whether or not +the given classname is either C<UNIVERSAL> itself, +or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance. + +=end original + +Returns a boolean status indicating whether or not +the given classname is either C<UNIVERSAL> itself, +or one of C<UNIVERSAL>'s parents by C<@ISA> inheritance. +(TBT) + +=begin original + +Any class for which this function returns true is +"universal" in the sense that all classes potentially +inherit methods from it. + +=end original + +Any class for which this function returns true is +"universal" in the sense that all classes potentially +inherit methods from it. +(TBT) + +=begin original + +For similar reasons to C<isarev> above, this flag is +permanent. Once it is set, it does not go away, even +if the class in question really isn't universal anymore. + +=end original + +For similar reasons to C<isarev> above, this flag is +permanent. Once it is set, it does not go away, even +if the class in question really isn't universal anymore. +(TBT) + +=head2 mro::invalidate_all_method_caches() + +=begin original + +Increments C<PL_sub_generation>, which invalidates method +caching in all packages. + +=end original + +Increments C<PL_sub_generation>, which invalidates method +caching in all packages. +(TBT) + +=head2 mro::method_changed_in($classname) + +=begin original + +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 L<constant> do. If you find another case, +please report it so we can either fix it or document +the exception here. + +=end original + +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 L<constant> do. If you find another case, +please report it so we can either fix it or document +the exception here. +(TBT) + +=head2 mro::get_pkg_gen($classname) + +=begin original + +Returns an integer which is incremented every time a +real local method in the package C<$classname> changes, +or the local C<@ISA> of C<$classname> is modified. + +=end original + +Returns an integer which is incremented every time a +real local method in the package C<$classname> changes, +or the local C<@ISA> of C<$classname> is modified. +(TBT) + +=begin original + +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/C<@ISA> +changes in superclasses. + +=end original + +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/C<@ISA> +changes in superclasses. +(TBT) + +=begin original + +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. + +=end original + +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. +(TBT) + +=begin original + +This integer normally starts off at a value of C<1> +when a package stash is instantiated. Calling it +on packages whose stashes do not exist at all will +return C<0>. If a package stash is completely +deleted (not a normal occurence, but it can happen +if someone does something like C<undef %PkgName::>), +the number will be reset to either C<0> or C<1>, +depending on how completely package was wiped out. + +=end original + +This integer normally starts off at a value of C<1> +when a package stash is instantiated. Calling it +on packages whose stashes do not exist at all will +return C<0>. If a package stash is completely +deleted (not a normal occurence, but it can happen +if someone does something like C<undef %PkgName::>), +the number will be reset to either C<0> or C<1>, +depending on how completely package was wiped out. +(TBT) + +=head2 next::method + +=begin original + +This is somewhat like C<SUPER>, 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, C<next::method> only uses the C3 MRO. + +=end original + +This is somewhat like C<SUPER>, 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, C<next::method> only uses the C3 MRO. +(TBT) + +=begin original + +One generally uses it like so: + +=end original + +One generally uses it like so: +(TBT) + + sub some_method { + my $self = shift; + my $superclass_answer = $self->next::method(@_); + return $superclass_answer + 1; + } + +=begin original + +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. + +=end original + +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. +(TBT) + +=begin original + +It can be called on an object or a class, of course. + +=end original + +It can be called on an object or a class, of course. +(TBT) + +=begin original + +The way it resolves which actual method to call is: + +=end original + +The way it resolves which actual method to call is: +(TBT) + +=over 4 + +=item 1 + +=begin original + +First, it determines the linearized C3 MRO of +the object or class it is being called on. + +=end original + +First, it determines the linearized C3 MRO of +the object or class it is being called on. +(TBT) + +=item 2 + +=begin original + +Then, it determines the class and method name +of the context it was invoked from. + +=end original + +Then, it determines the class and method name +of the context it was invoked from. +(TBT) + +=item 3 + +=begin original + +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. + +=end original + +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. +(TBT) + +=back + +=begin original + +Failure to find a next method will result in an +exception being thrown (see below for alternatives). + +=end original + +Failure to find a next method will result in an +exception being thrown (see below for alternatives). +(TBT) + +=begin original + +This is substantially different than the behavior +of C<SUPER> 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.) + +=end original + +This is substantially different than the behavior +of C<SUPER> 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.) +(TBT) + +=begin original + +B<Caveat>: Calling C<next::method> from methods defined outside the class: + +=end original + +B<Caveat>: Calling C<next::method> from methods defined outside the class: +(TBT) + +=begin original + +There is an edge case when using C<next::method> 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: + +=end original + +There is an edge case when using C<next::method> 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: +(TBT) + + *Foo::foo = sub { (shift)->next::method(@_) }; + +=begin original + +The problem exists because the anonymous subroutine being assigned to the +C<*Foo::foo> glob will show up in the call stack as being called +C<__ANON__> and not C<foo> as you might expect. Since C<next::method> uses +C<caller> to find the name of the method it was called in, it will fail in +this case. + +=end original + +The problem exists because the anonymous subroutine being assigned to the +C<*Foo::foo> glob will show up in the call stack as being called +C<__ANON__> and not C<foo> as you might expect. Since C<next::method> uses +C<caller> to find the name of the method it was called in, it will fail in +this case. +(TBT) + +=begin original + +But fear not, there's a simple solution. The module C<Sub::Name> will +reach into the perl internals and assign a name to an anonymous subroutine +for you. Simply do this: + +=end original + +But fear not, there's a simple solution. The module C<Sub::Name> will +reach into the perl internals and assign a name to an anonymous subroutine +for you. Simply do this: +(TBT) + + use Sub::Name 'subname'; + *Foo::foo = subname 'Foo::foo' => sub { (shift)->next::method(@_) }; + +=begin original + +and things will Just Work. + +=end original + +and things will Just Work. +(TBT) + +=head2 next::can + +=begin original + +This is similar to C<next::method>, but just returns either a code +reference or C<undef> to indicate that no further methods of this name +exist. + +=end original + +This is similar to C<next::method>, but just returns either a code +reference or C<undef> to indicate that no further methods of this name +exist. +(TBT) + +=head2 maybe::next::method + +=begin original + +In simple cases, it is equivalent to: + +=end original + +In simple cases, it is equivalent to: +(TBT) + + $self->next::method(@_) if $self->next_can; + +=begin original + +But there are some cases where only this solution +works (like C<goto &maybe::next::method>); + +=end original + +But there are some cases where only this solution +works (like C<goto &maybe::next::method>); +(TBT) + +=head1 SEE ALSO + +=head2 The original Dylan paper + +=over 4 + +=item L<http://www.webcom.com/haahr/dylan/linearization-oopsla96.html> + +=back + +=head2 The prototype Perl 6 Object Model uses C3 + +=over 4 + +=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/> + +=back + +=head2 Parrot now uses C3 + +=over 4 + +=item L<http://aspn.activestate.com/ASPN/Mail/Message/perl6-internals/2746631> + +=item L<http://use.perl.org/~autrijus/journal/25768> + +=back + +=head2 Python 2.3 MRO related links + +=over 4 + +=item L<http://www.python.org/2.3/mro.html> + +=item L<http://www.python.org/2.2.2/descrintro.html#mro> + +=back + +=head2 C3 for TinyCLOS + +=over 4 + +=item L<http://www.call-with-current-continuation.org/eggs/c3.html> + +=back + +=head2 Class::C3 + +=over 4 + +=item L<Class::C3> + +=back + +=head1 AUTHOR + +Brandon L. Black, E<lt>blbla****@gmail*****<gt> + +Based on Stevan Little's L<Class::C3> + +=cut +