Provided by: libex-monkeypatched-perl_0.03-1.1_all bug

NAME

       ex::monkeypatched - Experimental API for safe monkey-patching

SYNOPSIS

           use ex::monkeypatched 'Third::Party::Class' => (
               clunk => sub { ... },
               eth   => sub { ... },
           );

           use Foo::TopLevel; # provides Foo::Bar, which isn't a module
           use ex::monkeypatched -norequire => 'Foo::Bar' => (
               thwapp => sub { ... },
               urkk   => sub { ... },
           );

BACKGROUND

       The term "monkey patching" describes injecting additional methods into a class whose implementation you
       don't control.  If done without care, this is dangerous; the problematic case arises when:

       •   You add a method to a class;

       •   A newer version of the monkey-patched class adds another method of the same name

       •   And uses that new method in some other part of its own implementation.

       "ex::monkeypatched"  lets you do this sort of monkey-patching safely: before it injects a method into the
       target class, it checks whether the class already has a method of the same name.   If  it  finds  such  a
       method, it throws an exception (at compile-time with respect to the code that does the injection).

       See <http://aaroncrane.co.uk/talks/monkey_patching_subclassing/> for more details.

DESCRIPTION

       "ex::monkeypatched"  injects  methods when you "use" it.  There are two ways to invoke it with "use": one
       is easy but inflexible, and the other is more flexible but also more awkward.

       In the easy form, your "use" call should supply the name of a class to patch, and a listified  hash  from
       method names to code references implementing those methods:

           use ex::monkeypatched 'Some::Class' => (
               m1 => sub { ... },  # $x->m1 on Some::Class will now run this
               m2 => sub { ... },  # $x->m2 on Some::Class will now run this
           );

       In the flexible form, your "use" call supplies a single hashref saying what methods to create.  That last
       example can be done exactly like this:

           use ex::monkeypatched { class => 'Some::Class', methods => {
               m1 => sub { ... },  # $x->m1 on Some::Class will now run this
               m2 => sub { ... },  # $x->m2 on Some::Class will now run this
           } };

       However, this flexible form also lets you add a method of a single name to several classes at once:

           use ex::monkeypatched { method => 'm3', implementations => {
               'Some::BaseClass'     => sub { ... },
               'Some::Subclass::One' => sub { ... }
               'Some::Subclass::Two' => sub { ... },
           } };

       This  is  helpful  when  you  want  to  provide  a  method  for several related classes, with a different
       implementation in each of them.

       The classes to be patched will normally be  loaded  automatically  before  any  patching  is  done  (thus
       ensuring that all their base classes are also loaded).

       That  doesn't  work when you're trying to modify a class which can't be loaded directly; for example, the
       XML::LibXML  CPAN  distribution  provides  a  class  named  "XML::LibXML::Node",  but  trying   to   "use
       XML::LibXML::Node"  fails.   In that situation, you can tell "ex::monkeypatched" not to load the original
       class:

           use ex::monkeypatched -norequire => 'XML::LibXML::Node' => (
               clunk => sub { ... },
               eth   => sub { ... },
           );

           # Equivalently:
           use ex::monkeypatched -norequire => {
               class   => 'XML::LibXML::Node',
               methods => {
                   clunk => sub { ... },
                   eth   => sub { ... },
               },
           };

       Alternatively, you can inject methods after a class has already been loaded, using the "inject" method:

           use ex::monkeypatched;

           ex::monkeypatched->inject('XML::LibXML::Node' => (
               clunk => sub { ... },
               eth   => sub { ... },
           );

           # Equivalently:
           ex::monkeypatched->inject({ class => 'XML::LibXML::Node', methods => {
               clunk => sub { ... },
               eth   => sub { ... },
           }});

       Neither of these approaches ("-norequire" and "inject") loads the class in  question,  so  when  you  use
       them,  "ex::monkeypatched" is unable to guarantee that all the target class's methods have been loaded at
       the point the new methods are injected.

       The "ex::" prefix on the name of this module indicates that its API  is  still  considered  experimental.
       However,  the  underlying  code  has  been  in  use in production for an extended period, and seems to be
       reliable.

CAVEATS

       If the class you're monkeying around in uses "AUTOLOAD" to implement some of  its  methods,  and  doesn't
       also   implement  its  own  "can"  method  to  accurately  report  which  method  names  are  autoloaded,
       "ex::monkeypatched" will incorrectly assume that an autoloaded method does not exist.  The solution is to
       fix the broken class; implementing "AUTOLOAD" but not "can" is always an error.

AUTHOR

       Aaron Crane <arc@cpan.org>

LICENCE

       This library is free software; you can redistribute it and/or modify it under the terms of either the GNU
       General Public License version 2 or, at your option, the Artistic License.

perl v5.32.0                                       2021-01-04                             ex::monkeypatched(3pm)