Provided by: libclass-mixinfactory-perl_0.92-5_all bug

NAME

       Class::MixinFactory::ReadMe - About the Mixin Class Factory

SYNOPSIS

         package MyClass;
         use Class::MixinFactory -hasafactory;
         sub new { ... }
         sub foo { return "Foo Bar" }

         package MyClass::Logging;
         sub foo { warn "Calling foo"; (shift)->NEXT('foo', @_) }

         package MyClass::UpperCase;
         sub foo { uc( (shift)->NEXT('foo', @_) ) }

         package main;

         my $class = MyClass->class( 'Logging', 'UpperCase' );

         print $class->new()->foo();
         # Calls MyClass::Logging::foo, MyClass::UpperCase::foo, MyClass::foo

ABSTRACT

       This distribution facilitates the run-time generation of classes which inherit from a base class and some
       optional selection of mixin classes.

       A factory is provided to generate the mixed classes with multiple inheritance.  A NEXT method allows
       method redispatch up the inheritance chain.

MOTIVATION

   The Challenge
       When developing an object class that will be used by different people for different purposes, I find
       myself drawn to solutions in which a minimal base class provides the shared behavior they all need, and a
       collection of subclasses provides layers of additional functionality.

       For example, consider a text templating framework, which might be separated into several elements:

       •   a base class, which provides methods to convert marked-up text into runnable code,

       •   an extension which enhances security by running the code in a Safe compartment,

       •   an extension which feeds output through an HTML-escaping filter, and

       •   an extension which records internal profiling data for benchmarking purposes.

       (See Text::MicroMason for an example of this design.)

   A Bad Approach
       A naive implementation of this might use a subclass for each behaviour, and look like the following:

                           +---------+
                           |   Base  |
                           +---------+
                                |
              +-----------------+-----------------+
              v                 v                 v
         +---------+       +---------+       +---------+
         |Benchmark|       |  Filter |       |   Safe  | @ISA=qw(Base)
         +---------+       +---------+       +---------+

       The well-known problem with this implementation appears when you want to combine several features:

                           +---------+
                           |   Base  |
                           +---------+
                                |
              +-----------------+-----------------+
              v                 v                 v
         +---------+       +---------+       +---------+
         |Benchmark|       |  Filter |       |   Safe  | @ISA=qw(Base)
         +---------+       +---------+       +---------+
                                |                 |
                                +--------+--------+
                                         v
                                  +-------------+
                                  | Safe_Filter | @ISA=qw(Filter Safe)
                                  +-------------+

       This  is the dreaded "diamond inheritance" problem: if Base provides a compile() method, which Filter and
       Safe each override to perform additional actions before or after calling  SUPER::compile(),  how  can  we
       ensure they are all called in the correct sequence?

   A Good Approach
       The  standard  software engineering solution is to replace the use of inheritance with decomposition into
       several different classes of objects,  which  then  cooperate  through  decoration  and  delegation;  for
       example,  using  separate  classes  for a resolver, a lexer, a parser, a compiler, and an output channel.
       (See HTML::Mason for an example of this design.)

       Indeed, composition is an underutilized design technique, and there are many times  when  inheritance  is
       not  the best tool to use. But of course, in Perl there's more than one way to solve this problem, one of
       which is facilitated by this distribution.

   A Different Approach
       We can rearrange our class hierarchy to avoid diamond inheritance by using a base  and  a  collection  of
       mixin classes, which don't directly inherit from the base class:

         +---------+       +---------+       +---------+       +---------+
         |Benchmark|       |  Filter |       |   Safe  |       |   Base  |
         +---------+       +---------+       +---------+       +---------+
                                |                 |                 |
                                +-----------------+-----------------+
                                                  v
                                           +-------------+
                                           | Safe_Filter | @ISA=qw(Filter
                                           +-------------+     Safe Base)

       However, in this condition our mixin classes can't call SUPER methods at all! Instead, another redispatch
       mechanism  is  needed,  one  that  is  able  to back-track through the inheritance tree and explore other
       branches. (See NEXT for such an implementation.)

       The order in which mixins are stacked is significant, so the caller does need to have some  understanding
       of  how their behaviors interact. For example, you'd typically want to ensure that the Benchmarking mixin
       was the first in the chain, so that it could time everything later in the sequence.

   This Distribution
       The Class::MixinFactory distribution provides several elements to facilitate this kind of  dynamic  mixin
       architecture.  The top level package is just a facade that loads the other necessary classes and provides
       a few import options for compile-time convenience. (See Class::MixinFactory.)

       To generate an object with some combination of mixins, you first use a mixin factory to generate a  mixed
       class.  If a class with that combination of classes has already been created, it is reused. You can add a
       factory method to your base class, create a separate factory object, or  inherit  to  produce  a  factory
       class. (See Class::MixinFactory::Factory.)

       To  allow  mixin classes to redispatch to subsequent classes, all mixed classes also inherit from a class
       which provides a NEXT() method. (If you would prefer, your mixin class can alternately use  the  AUTOLOAD
       solution  provided  by the NEXT::ACTUAL module from CPAN, or any other equivalent re-dispatch mechanism.)
       (See Class::MixinFactory::NEXT.)

RELATED MODULES

       There are number of other modules on CPAN  that  also  support  mixins,  method  importing,  or  run-time
       multiple inheritance, while others don't use mixins but are addressing a similar area of concern.

       •   The  mixin,  Class::Mixin,  and  Spiffy  modules  support mixin classes but don't have a configurable
           factory object or support run-time mixin selection.

       •   The  Class::Mix  and  Class::Mutator  modules  provide  run-time  class  generation   with   multiple
           inheritance, but don't provide a configurable factory object or a redispatch technique.

       •   The Class::Factory module has a factory interface, but doesn't support multiple inheritance.

       •   The NEXT module provides a backtracking equivalent to SUPER similar to the NEXT method included here,
           but uses AUTOLOAD rather than a universal method.

       •   The Class::Delegate and other modules support decoration to address this problem via decomposition.

       •   The  Class::Role,  Class::Roles and Class::Trait modules support composing shared behaviors into your
           class.

VERSION

       This is version 0.92.

       Elements of the interface remain open to change.

BUGS

       This module is new and relatively untested.

       Please report any problems you encounter to the author at the below address.

INSTALLATION

       This module should work with any version of Perl 5, without platform dependencies or  additional  modules
       beyond the core distribution.

       You should be able to install this module using the CPAN shell interface:

         perl -MCPAN -e 'install Class::MixinFactory'

       Alternately,  you  may  retrieve  this  package  from  CPAN  ("http://search.cpan.org/~evo/") or from the
       author's site ("http://www.evoscript.org/Class-MixinFactory").

       After downloading the distribution, follow the normal procedure to  unpack  and  install  it,  using  the
       commands shown below or their local equivalents on your system:

         tar xzf Class-MixinFactory-*.tar.gz
         cd Class-MixinFactory-*
         perl Makefile.PL
         make test && sudo make install

SUPPORT

       If  you have questions or feedback about this module, please feel free to contact the author at the below
       address. Although there is no formal support program, I do attempt to answer email promptly.

       I would be particularly interested in any suggestions towards improving the documentation, correcting any
       Perl-version or platform dependencies, as well as general feedback and suggested additions.

       Bug reports that contain a failing test case are greatly  appreciated,  and  suggested  patches  will  be
       promptly considered for inclusion in future releases.

       To       report      bugs      via      the      CPAN      web      tracking      system,      go      to
       "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Class-MixinFactory"        or        send        mail        to
       "Dist=Class-MixinFactory#rt.cpan.org", replacing "#" with "@".

       If  you've found this module useful or have feedback about your experience with it, consider sharing your
       opinion   with   other   Perl   users   by   posting   your   comment   to    CPAN's    ratings    system
       ("http://cpanratings.perl.org/rate/?distribution=Class-MixinFactory").

       For    more    general    discussion,    you    may    wish    to    post    a   message   on   PerlMonks
       ("http://perlmonks.org/?node=Seekers%20of%20Perl%20Wisdom")  or  on  the  comp.lang.perl.misc   newsgroup
       ("http://groups.google.com/groups?group=comp.lang.perl.misc").

AUTHOR

       Developed  by  Matthew  Simon  Cavalletto at Evolution Softworks.  You may contact the author directly at
       "evo#cpan.org" or "simonm#cavalletto.org", replacing "#" with "@".

       Custom development and technical consulting are available at "www.evolutionsoftworks.com". More free Perl
       software is available at "www.evoscript.org".

THANKS

       My sincere thanks to the Perl Monks community for their feedback on earlier versions of this commentary.

         http://perlmonks.org/index.pl?node_id=398061
         http://perlmonks.org/index.pl?node_id=399040

LICENSE

       Copyright 2004 Matthew Simon Cavalletto.

       You may use, modify, and distribute this software under the same terms as Perl.

perl v5.36.0                                       2022-10-22                          MixinFactory::ReadMe(3pm)