Spec-Zone .ru
спецификации, руководства, описания, API
Spec-Zone .ru
спецификации, руководства, описания, API
Библиотека разработчика Mac Разработчик
Поиск

 

Эта страница руководства для  версии 10.9 Mac OS X

Если Вы выполняете различную версию  Mac OS X, просматриваете документацию локально:

Читать страницы руководства

Страницы руководства предназначаются как справочник для людей, уже понимающих технологию.

  • Чтобы изучить, как руководство организовано или узнать о синтаксисе команды, прочитайте страницу руководства для страниц справочника (5).

  • Для получения дополнительной информации об этой технологии, ищите другую документацию в Библиотеке Разработчика Apple.

  • Для получения общей информации о записи сценариев оболочки, считайте Shell, Пишущий сценарий Учебника для начинающих.



Moose::Cookbook::Extending::Recipe1(3)ser Contributed Perl Documentationose::Cookbook::Extending::Recipe1(3)



NAME
       Moose::Cookbook::Extending::Recipe1 - Moose extension overview

VERSION
       version 2.0205

DESCRIPTION
       Moose provides several ways in which extensions can hook into Moose and change its behavior. Moose
       also has a lot of behavior that can be changed. This recipe will provide an overview of each
       extension method and give you some recommendations on what tools to use.

       If you haven't yet read the recipes on metaclasses, go read those first. You can't write Moose
       extensions without understanding the metaclasses, and those recipes also demonstrate some basic
       extension mechanisms, such as metaclass subclasses and traits.

   Playing Nice With Others
       One of the goals of this overview is to help you build extensions that cooperate well with other
       extensions. This is especially important if you plan to release your extension to CPAN.

       Moose comes with several modules that exist to help your write cooperative extensions. These are
       Moose::Exporter and Moose::Util::MetaRole. By using these two modules, you will ensure that your
       extension works with both the Moose core features and any other CPAN extension using those modules.

PARTS OF Moose YOU CAN EXTEND
       The types of things you might want to do in Moose extensions fall into a few broad categories.

   Metaclass Extensions
       One way of extending Moose is by extending one or more Moose metaclasses. For example, in
       Moose::Cookbook::Meta::Recipe4 we saw a metaclass subclass that added a "table" attribute to the
       metaclass. If you were writing an ORM, this would be a logical extension.

       Many of the Moose extensions on CPAN work by providing an attribute metaclass extension. For example,
       the MooseX::AttributeHelpers distribution provides a new attribute metaclass that lets you delegate
       behavior to a non-object attribute (a hashref or simple number).

       A metaclass extension can be packaged as a subclass or a role/trait. If you can, we recommend using
       traits instead of subclasses, since it's much easier to combine disparate traits than it is to
       combine a bunch of subclasses.

       When your extensions are implemented as roles, you can apply them with the Moose::Util::MetaRole
       module.

   Providing Sugar Functions
       As part of a metaclass extension, you may also want to provide some sugar functions, just like
       Moose.pm does. Moose provides a helper module called Moose::Exporter that makes this much simpler. We
       will be use Moose::Exporter in several of the extension recipes.

   Object Class Extensions
       Another common Moose extension technique is to change the default object class's behavior. For
       example, the MooseX::Singleton extension changes the behavior of your objects so that they are
       singletons. The MooseX::StrictConstructor extension makes the constructor reject arguments which
       don't match its attributes.

       Object class extensions often include metaclass extensions as well. In particular, if you want your
       object extension to work when a class is made immutable, you may need to extend some or all of the
       Moose::Meta::Instance, Moose::Meta::Method::Constructor, and Moose::Meta::Method::Destructor objects.

       The Moose::Util::MetaRole module lets you apply roles to the base object class, as well as the meta
       classes just mentioned.

   Providing a Role
       Some extensions come in the form of a role for you to consume. The MooseX::Object::Pluggable
       extension is a great example of this. In fact, despite the "MooseX" name, it does not actually change
       anything about Moose's behavior. Instead, it is just a role that an object which wants to be
       pluggable can consume.

       If you are implementing this sort of extension, you don't need to do anything special. You simply
       create a role and document that it should be used via the normal "with" sugar:

          package MyApp::User;

          use Moose;

          with 'MooseX::My::Role';

   New Types
       Another common Moose extension is a new type for the Moose type system. In this case, you simply
       create a type in your module. When people load your module, the type is created, and they can refer
       to it by name after that. The MooseX::Types::URI and MooseX::Types::DateTime distributions are two
       good examples of how this works. These both build on top of the MooseX::Types extension.

ROLES VS TRAITS VS SUBCLASSES
       It is important to understand that roles and traits are the same thing. A trait is simply a role
       applied to a instance. The only thing that may distinguish the two is that a trait can be packaged in
       a way that lets Moose resolve a short name to a class name. In other words, with a trait, the caller
       can refer to it by a short name like "Big", and Moose will resolve it to a class like
       "MooseX::Embiggen::Meta::Attribute::Role::Big".

       See Moose::Cookbook::Meta::Recipe3 and Moose::Cookbook::Meta::Recipe5 for examples of traits in
       action. In particular, both of these recipes demonstrate the trait resolution mechanism.

       Implementing an extension as a (set of) metaclass or base object role(s) will make your extension
       more cooperative. It is hard for an end-user to effectively combine together multiple metaclass
       subclasses, but it is very easy to combine roles.

USING YOUR EXTENSION
       There are a number of ways in which an extension can be applied. In some cases you can provide
       multiple ways of consuming your extension.

   Extensions as Metaclass Traits
       If your extension is available as a trait, you can ask end users to simply specify it in a list of
       traits. Currently, this only works for (class) metaclass and attribute metaclass traits:

         use Moose -traits => [ 'Big', 'Blue' ];

         has 'animal' => (
             traits => [ 'Big', 'Blue' ],
             ...
         );

       If your extension applies to any other metaclass, or the object base class, you cannot use the trait
       mechanism.

       The benefit of the trait mechanism is that is very easy to see where a trait is applied in the code,
       and consumers have fine-grained control over what the trait applies to. This is especially true for
       attribute traits, where you can apply the trait to just one attribute in a class.

   Extensions as Metaclass (and Base Object) Subclasses
       Moose does not provide any simple APIs for consumers to use a subclass extension, except for
       attribute metaclasses. The attribute declaration options include a "metaclass" option a consumer of
       your extension can use to specify your subclass.

       This is one reason why implementing an extension as a subclass can be a poor choice. However, you can
       force the use of certain subclasses at import time by calling "Moose->init_meta" for the caller, and
       providing an alternate metaclass or base object class.

       If you do want to do this, you should look at using Moose::Exporter to re-export the Moose.pm sugar
       function. With Moose::Exporter, if your exporting class has an "init_meta" method, Moose::Exporter
       makes sure that this "init_meta" method gets called when your class is imported.

       Then in your "init_meta" you can arrange for the caller to use your subclasses:

         package MooseX::Embiggen;

         use Moose ();
         use Moose::Exporter;

         use MooseX::Embiggen::Meta::Class;
         use MooseX::Embiggen::Object;

         Moose::Exporter->setup_import_methods( also => 'Moose' );

         sub init_meta {
             shift;    # just your package name
             my %options = @_;

             return Moose->init_meta(
                 for_class  => $options{for_class},
                 metaclass  => 'MooseX::Embiggen::Meta::Class',
                 base_class => 'MooseX::Embiggen::Object',
             );
         }

       NOTE: Make sure that your "init_meta" returns the metaclass object, just as "Moose->init_meta" does.

   Extensions as Metaclass (and Base Object) Roles
       Implementing your extensions as metaclass roles makes your extensions easy to apply, and cooperative
       with other role-based extensions for metaclasses.

       Just as with a subclass, you will probably want to package your extensions for consumption with a
       single module that uses Moose::Exporter. However, in this case, you will use Moose::Util::MetaRole to
       apply all of your roles. The advantage of using this module is that it preserves any subclassing or
       roles already applied to the user's metaclasses. This means that your extension is cooperative by
       default, and consumers of your extension can easily use it with other role-based extensions. Most
       uses of Moose::Util::MetaRole can be handled by Moose::Exporter directly; see the Moose::Exporter
       docs.

         package MooseX::Embiggen;

         use Moose ();
         use Moose::Exporter;

         use MooseX::Embiggen::Role::Meta::Class;
         use MooseX::Embiggen::Role::Meta::Attribute;
         use MooseX::Embiggen::Role::Meta::Method::Constructor;
         use MooseX::Embiggen::Role::Object;

         my ( $import, $unimport, $init_meta ) = Moose::Exporter->build_import_methods(
             also => ['Moose'] metaclass_roles =>
                 ['MooseX::Embiggen::Role::Meta::Class'],
             attribute_metaclass_roles => ['MooseX::Embiggen::Role::Meta::Attribute'],
             constructor_class_roles =>
                 ['MooseX::Embiggen::Role::Meta::Method::Constructor'],
             base_class_roles => ['MooseX::Embiggen::Role::Object'],
             install          => [qw(import unimport)],
         );

         sub init_meta {
             my $package = shift;
             my %options = @_;
             Moose->init_meta(%options);
             return $package->$init_meta(%options);
         }

       As you can see from this example, you can use Moose::Util::MetaRole to apply roles to any metaclass,
       as well as the base object class. If some other extension has already applied its own roles, they
       will be preserved when your extension applies its roles, and vice versa.

   Providing Sugar
       With Moose::Exporter, you can also export your own sugar functions, as well as those from other
       modules:

         package MooseX::Embiggen;

         use Moose ();
         use Moose::Exporter;

         Moose::Exporter->setup_import_methods(
             with_meta => ['embiggen'],
             also      => 'Moose',
         );

         sub embiggen {
             my $meta = shift;
             $meta->embiggen(@_);
         }

       And then the consumer of your extension can use your "embiggen" sub:

         package Consumer;

         use MooseX::Embiggen;

         extends 'Thing';

         embiggen ...;

       This can be combined with metaclass and base class roles quite easily.

LEGACY EXTENSION MECHANISMS
       Before the existence of Moose::Exporter and Moose::Util::MetaRole, there were a number of other ways
       to extend Moose. In general, these methods were less cooperative, and only worked well with a single
       extension.

       These methods include metaclass.pm, Moose::Policy (which uses metaclass.pm under the hood), and
       various hacks to do what Moose::Exporter does. Please do not use these for your own extensions.

       Note that if you write a cooperative extension, it should cooperate with older extensions, though
       older extensions generally do not cooperate with each other.

CONCLUSION
       If you can write your extension as one or more metaclass and base object roles, please consider doing
       so. Make sure to read the docs for Moose::Exporter and Moose::Util::MetaRole as well.

AUTHOR
       Stevan Little <stevan@iinteractive.com>

COPYRIGHT AND LICENSE
       This software is copyright (c) 2011 by Infinity Interactive, Inc..

       This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5
       programming language system itself.



perl v5.12.5                                     2011-09-06           Moose::Cookbook::Extending::Recipe1(3)

Сообщение о проблемах

Способ сообщить о проблеме с этой страницей руководства зависит от типа проблемы:

Ошибки содержания
Ошибки отчета в содержании этой документации к проекту Perl. (См. perlbug (1) для инструкций представления.)
Отчеты об ошибках
Сообщите об ошибках в функциональности описанного инструмента или API к Apple через Генератор отчетов Ошибки и к проекту Perl, использующему perlbug (1).
Форматирование проблем
Отчет, форматирующий ошибки в интерактивной версии этих страниц со ссылками на отзыв ниже.