dwww Home | Manual pages | Find package

Moose::Cookbook::Meta:UseMoose::Cookbook::Meta::GlobRefoInstanceMetaclass(3pm)

NAME
       Moose::Cookbook::Meta::GlobRef_InstanceMetaclass - Creating a glob
       reference meta-instance class

VERSION
       version 2.2203

SYNOPSIS
         package My::Meta::Instance;

         use Scalar::Util qw( weaken );
         use Symbol qw( gensym );

         use Moose::Role;

         sub create_instance {
             my $self = shift;
             my $sym = gensym();
             bless $sym, $self->_class_name;
         }

         sub clone_instance {
             my ( $self, $instance ) = @_;

             my $new_sym = gensym();
             %{*$new_sym} = %{*$instance};

             bless $new_sym, $self->_class_name;
         }

         sub get_slot_value {
             my ( $self, $instance, $slot_name ) = @_;
             return *$instance->{$slot_name};
         }

         sub set_slot_value {
             my ( $self, $instance, $slot_name, $value ) = @_;
             *$instance->{$slot_name} = $value;
         }

         sub deinitialize_slot {
             my ( $self, $instance, $slot_name ) = @_;
             delete *$instance->{$slot_name};
         }

         sub is_slot_initialized {
             my ( $self, $instance, $slot_name ) = @_;
             exists *$instance->{$slot_name};
         }

         sub weaken_slot_value {
             my ( $self, $instance, $slot_name ) = @_;
             weaken *$instance->{$slot_name};
         }

         sub inline_create_instance {
             my ( $self, $class_variable ) = @_;
             return 'do { my $sym = Symbol::gensym(); bless $sym, ' . $class_variable . ' }';
         }

         sub inline_slot_access {
             my ( $self, $instance, $slot_name ) = @_;
             return '*{' . $instance . '}->{' . $slot_name . '}';
         }

         package MyApp::User;

         use Moose;
         Moose::Util::MetaRole::apply_metaroles(
             for => __PACKAGE__,
             class_metaroles => {
                 instance => ['My::Meta::Instance'],
             },
         );

         has 'name' => (
             is  => 'rw',
             isa => 'Str',
         );

         has 'email' => (
             is  => 'rw',
             isa => 'Str',
         );

DESCRIPTION
       This recipe shows how to build your own meta-instance. The meta
       instance is the metaclass that creates object instances and helps
       manages access to attribute slots.

       In this example, we're creating a meta-instance that is based on a glob
       reference rather than a hash reference. This example is largely based
       on the Piotr Roszatycki's MooseX::GlobRef module.

       Our extension is a role which will be applied to Moose::Meta::Instance,
       which creates hash reference based objects. We need to override all the
       methods which make assumptions about the object's data structure.

       The first method we override is "create_instance":

         sub create_instance {
             my $self = shift;
             my $sym = gensym();
             bless $sym, $self->_class_name;
         }

       This returns an glob reference which has been blessed into our meta-
       instance's associated class.

       We also override "clone_instance" to create a new array reference:

         sub clone_instance {
             my ( $self, $instance ) = @_;

             my $new_sym = gensym();
             %{*$new_sym} = %{*$instance};

             bless $new_sym, $self->_class_name;
         }

       After that, we have a series of methods which mediate access to the
       object's slots (attributes are stored in "slots"). In the default
       instance class, these expect the object to be a hash reference, but we
       need to change this to expect a glob reference instead.

         sub get_slot_value {
             my ( $self, $instance, $slot_name ) = @_;
             *$instance->{$slot_name};
         }

       This level of indirection probably makes our instance class slower than
       the default. However, when attribute access is inlined, this lookup
       will be cached:

         sub inline_slot_access {
             my ( $self, $instance, $slot_name ) = @_;
             return '*{' . $instance . '}->{' . $slot_name . '}';
         }

       The code snippet that the "inline_slot_access" method returns will get
       "eval"'d once per attribute.

       Finally, we use this meta-instance in our "MyApp::User" class:

         Moose::Util::MetaRole::apply_metaroles(
             for => __PACKAGE__,
             class_metaroles => {
                 instance => ['My::Meta::Instance'],
             },
         );

       We actually don't recommend the use of Moose::Util::MetaRole directly
       in your class in most cases. Typically, this would be provided by a
       Moose::Exporter-based module which handles applying the role for you.

CONCLUSION
       This recipe shows how to create your own meta-instance class. It's
       unlikely that you'll need to do this yourself, but it's interesting to
       take a peek at how Moose works under the hood.

SEE ALSO
       There are a few meta-instance class extensions on CPAN:

       •   MooseX::Singleton

           This module extends the instance class in order to ensure that the
           object is a singleton. The instance it uses is still a blessed hash
           reference.

       •   MooseX::GlobRef

           This module makes the instance a blessed glob reference. This lets
           you use a handle as an object instance.

AUTHORS
       •   Stevan Little <stevan@cpan.org>

       •   Dave Rolsky <autarch@urth.org>

       •   Jesse Luehrs <doy@cpan.org>

       •   Shawn M Moore <sartak@cpan.org>

       •   יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>

       •   Karen Etheridge <ether@cpan.org>

       •   Florian Ragwitz <rafl@debian.org>

       •   Hans Dieter Pearcey <hdp@cpan.org>

       •   Chris Prather <chris@prather.org>

       •   Matt S Trout <mstrout@cpan.org>

COPYRIGHT AND LICENSE
       This software is copyright (c) 2006 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.36.0             Moose::Cookbook::Meta::GlobRef_InstanceMetaclass(3pm)

Generated by dwww version 1.15 on Wed Jun 26 18:04:37 CEST 2024.