diff options
Diffstat (limited to 'pod')
-rw-r--r-- | pod/perlapi.pod | 33 | ||||
-rw-r--r-- | pod/perlboot.pod | 8 | ||||
-rw-r--r-- | pod/perlobj.pod | 5 | ||||
-rw-r--r-- | pod/perltoot.pod | 63 |
4 files changed, 88 insertions, 21 deletions
diff --git a/pod/perlapi.pod b/pod/perlapi.pod index cc649f0e78..7c0aa88403 100644 --- a/pod/perlapi.pod +++ b/pod/perlapi.pod @@ -2810,20 +2810,25 @@ of the given stash, so that they might notice the changes in this one. Ideally, all instances of C<PL_sub_generation++> in -the perl source outside of C<mro.c> should be -replaced by calls to this. This conversion is -nearly complete. - -Perl has always had problems with method caches -getting out of sync when one directly manipulates -stashes via things like C<%{Foo::} = %{Bar::}> or -C<${Foo::}{bar} = ...> or the equivalent. If -you do this in core or XS code, call this afterwards -on the destination stash to get things back in sync. - -If you're doing such a thing from pure perl, use -C<mro::method_changed_in(classname)>, which -just calls this. +perl source outside of C<mro.c> should be +replaced by calls to this. + +Perl automatically handles most of the common +ways a method might be redefined. However, there +are a few ways you could change a method in a stash +without the cache code noticing, in which case you +need to call this method afterwards: + +1) Directly manipulating the stash HV entries from +XS code. + +2) Assigning a reference to a readonly scalar +constant into a stash entry in order to create +a constant subroutine (like constant.pm +does). + +This same method is available from pure perl +via, C<mro::method_changed_in(classname)>. void mro_method_changed_in(HV* stash) diff --git a/pod/perlboot.pod b/pod/perlboot.pod index 927777d040..bd39c44ea7 100644 --- a/pod/perlboot.pod +++ b/pod/perlboot.pod @@ -238,10 +238,10 @@ not a simple single value, because on rare occasions, it makes sense to have more than one parent class searched for the missing methods. If C<Animal> also had an C<@ISA>, then we'd check there too. The -search is recursive, depth-first, left-to-right in each C<@ISA>. -Typically, each C<@ISA> has only one element (multiple elements means -multiple inheritance and multiple headaches), so we get a nice tree of -inheritance. +search is recursive, depth-first, left-to-right in each C<@ISA> by +default (see L<mro> for alternatives). Typically, each C<@ISA> has +only one element (multiple elements means multiple inheritance and +multiple headaches), so we get a nice tree of inheritance. When we turn on C<use strict>, we'll get complaints on C<@ISA>, since it's not a variable containing an explicit package name, nor is it a diff --git a/pod/perlobj.pod b/pod/perlobj.pod index 6cfa20ce8e..b6638e81b7 100644 --- a/pod/perlobj.pod +++ b/pod/perlobj.pod @@ -151,8 +151,9 @@ There is a special array within each package called @ISA, which says where else to look for a method if you can't find it in the current package. This is how Perl implements inheritance. Each element of the @ISA array is just the name of another package that happens to be a -class package. The classes are searched (depth first) for missing -methods in the order that they occur in @ISA. The classes accessible +class package. The classes are searched for missing methods in +depth-first, left-to-right order by default (see L<mro> for alternative +search order and other in-depth information). The classes accessible through @ISA are known as base classes of the current class. All classes implicitly inherit from class C<UNIVERSAL> as their diff --git a/pod/perltoot.pod b/pod/perltoot.pod index 4a212fba91..5180306688 100644 --- a/pod/perltoot.pod +++ b/pod/perltoot.pod @@ -1016,7 +1016,8 @@ dubiously-OO languages like C++. The way it works is actually pretty simple: just put more than one package name in your @ISA array. When it comes time for Perl to go finding methods for your object, it looks at each of these packages in order. -Well, kinda. It's actually a fully recursive, depth-first order. +Well, kinda. It's actually a fully recursive, depth-first order by +default (see L<mro> for alternate method resolution orders). Consider a bunch of @ISA arrays like this: @First::ISA = qw( Alpha ); @@ -1120,6 +1121,66 @@ higher available. This is not the same as loading in that exact version number. No mechanism currently exists for concurrent installation of multiple versions of a module. Lamentably. +=head2 Deeper UNIVERSAL details + +It is also valid (though perhaps unwise in most cases) to put other +packages' names in @UNIVERSAL::ISA. These packages will also be +implicitly inherited by all classes, just as UNIVERSAL itself is. +However, neither UNIVERSAL nor any of its parents from the @ISA tree +are explicit base classes of all objects. To clarify, given the +following: + + @UNIVERSAL::ISA = ('REALLYUNIVERSAL'); + + package REALLYUNIVERSAL; + sub special_method { return "123" } + + package Foo; + sub normal_method { return "321" } + +Calling Foo->special_method() will return "123", but calling +Foo->isa('REALLYUNIVERSAL') or Foo->isa('UNIVERSAL') will return +false. + +If your class is using an alternate mro like C3 (see +L<mro>), method resolution within UNIVERSAL / @UNIVERSAL::ISA will +still occur in the default depth-first left-to-right manner, +after the class's C3 mro is exhausted. + +All of the above is made more intuitive by realizing what really +happens during method lookup, which is roughly like this +ugly pseudo-code: + + get_mro(class) { + # recurses down the @ISA's starting at class, + # builds a single linear array of all + # classes to search in the appropriate order. + # The method resolution order (mro) to use + # for the ordering is whichever mro "class" + # has set on it (either default (depth first + # l-to-r) or C3 ordering). + # The first entry in the list is the class + # itself. + } + + find_method(class, methname) { + foreach $class (get_mro(class)) { + if($class->has_method(methname)) { + return ref_to($class->$methname); + } + } + foreach $class (get_mro(UNIVERSAL)) { + if($class->has_method(methname)) { + return ref_to($class->$methname); + } + } + return undef; + } + +However the code that implements UNIVERSAL::isa does not +search in UNIVERSAL itself, only in the package's actual +@ISA. + =head1 Alternate Object Representations Nothing requires objects to be implemented as hash references. An object |