phpman > perldoc > Moose::Cookbook::Meta::GlobRef_InstanceMetaclass

Markdown | JSON | MCP    

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

VERSION
    version 2.2200

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 AT cpan.org>

    *   Dave Rolsky <autarch AT urth.org>

    *   Jesse Luehrs <doy AT cpan.org>

    *   Shawn M Moore <sartak AT cpan.org>

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

    *   Karen Etheridge <ether AT cpan.org>

    *   Florian Ragwitz <rafl AT debian.org>

    *   Hans Dieter Pearcey <hdp AT cpan.org>

    *   Chris Prather <chris AT prather.org>

    *   Matt S Trout <mstrout AT 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.

Moose::Cookbook::Meta::GlobRef_InstanceMetaclass
NAME VERSION SYNOPSIS DESCRIPTION CONCLUSION SEE ALSO AUTHORS COPYRIGHT AND LICENSE

Generated by phpman local Author: Che Dong Under GNU General Public License
2026-06-15 06:52 @216.73.216.200
CrawledBy Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
Valid XHTML 1.0 TransitionalValid CSS!

^_back to top