| Moose::Cookbook::Meta::GlobRef_InstanceMetaclass - phpMan
Moose::Cookbook::Meta::GlobRef_UseraContribuMoose::Cookbook::Meta::GlobRef_InstanceMetaclass(3pm)
NAME
Moose::Cookbook::Meta::GlobRef_InstanceMetaclass - Creating a glob reference meta-instance
class
VERSION
version 2.1213
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.little AT iinteractive.com>
· Dave Rolsky <autarch AT urth.org>
· Jesse Luehrs <doy AT tozt.net>
· Shawn M Moore <code AT sartak.org>
· XXXX XXX'XX (Yuval Kogman) <nothingmuch AT woobling.org>
· Karen Etheridge <ether AT cpan.org>
· Florian Ragwitz <rafl AT debian.org>
· Hans Dieter Pearcey <hdp AT weftsoar.net>
· Chris Prather <chris AT prather.org>
· Matt S Trout <mst AT shadowcat.uk>
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.20.1 Moose::Cookbook::Meta::GlobRef_InstanceMetaclass(3pm)
|