1Moose::Cookbook::Meta::UGsleorbRCMeoofno_tsIreni:sb:tuCatoneocdkebMPoeeotrkal:c:lDMaoesctsua(m:3e:)nGtlaotbiRoenf_InstanceMetaclass(3)
2
3
4
6 Moose::Cookbook::Meta::GlobRef_InstanceMetaclass - Creating a glob
7 reference meta-instance class
8
10 version 2.2201
11
13 package My::Meta::Instance;
14
15 use Scalar::Util qw( weaken );
16 use Symbol qw( gensym );
17
18 use Moose::Role;
19
20 sub create_instance {
21 my $self = shift;
22 my $sym = gensym();
23 bless $sym, $self->_class_name;
24 }
25
26 sub clone_instance {
27 my ( $self, $instance ) = @_;
28
29 my $new_sym = gensym();
30 %{*$new_sym} = %{*$instance};
31
32 bless $new_sym, $self->_class_name;
33 }
34
35 sub get_slot_value {
36 my ( $self, $instance, $slot_name ) = @_;
37 return *$instance->{$slot_name};
38 }
39
40 sub set_slot_value {
41 my ( $self, $instance, $slot_name, $value ) = @_;
42 *$instance->{$slot_name} = $value;
43 }
44
45 sub deinitialize_slot {
46 my ( $self, $instance, $slot_name ) = @_;
47 delete *$instance->{$slot_name};
48 }
49
50 sub is_slot_initialized {
51 my ( $self, $instance, $slot_name ) = @_;
52 exists *$instance->{$slot_name};
53 }
54
55 sub weaken_slot_value {
56 my ( $self, $instance, $slot_name ) = @_;
57 weaken *$instance->{$slot_name};
58 }
59
60 sub inline_create_instance {
61 my ( $self, $class_variable ) = @_;
62 return 'do { my $sym = Symbol::gensym(); bless $sym, ' . $class_variable . ' }';
63 }
64
65 sub inline_slot_access {
66 my ( $self, $instance, $slot_name ) = @_;
67 return '*{' . $instance . '}->{' . $slot_name . '}';
68 }
69
70 package MyApp::User;
71
72 use Moose;
73 Moose::Util::MetaRole::apply_metaroles(
74 for => __PACKAGE__,
75 class_metaroles => {
76 instance => ['My::Meta::Instance'],
77 },
78 );
79
80 has 'name' => (
81 is => 'rw',
82 isa => 'Str',
83 );
84
85 has 'email' => (
86 is => 'rw',
87 isa => 'Str',
88 );
89
91 This recipe shows how to build your own meta-instance. The meta
92 instance is the metaclass that creates object instances and helps
93 manages access to attribute slots.
94
95 In this example, we're creating a meta-instance that is based on a glob
96 reference rather than a hash reference. This example is largely based
97 on the Piotr Roszatycki's MooseX::GlobRef module.
98
99 Our extension is a role which will be applied to Moose::Meta::Instance,
100 which creates hash reference based objects. We need to override all the
101 methods which make assumptions about the object's data structure.
102
103 The first method we override is "create_instance":
104
105 sub create_instance {
106 my $self = shift;
107 my $sym = gensym();
108 bless $sym, $self->_class_name;
109 }
110
111 This returns an glob reference which has been blessed into our meta-
112 instance's associated class.
113
114 We also override "clone_instance" to create a new array reference:
115
116 sub clone_instance {
117 my ( $self, $instance ) = @_;
118
119 my $new_sym = gensym();
120 %{*$new_sym} = %{*$instance};
121
122 bless $new_sym, $self->_class_name;
123 }
124
125 After that, we have a series of methods which mediate access to the
126 object's slots (attributes are stored in "slots"). In the default
127 instance class, these expect the object to be a hash reference, but we
128 need to change this to expect a glob reference instead.
129
130 sub get_slot_value {
131 my ( $self, $instance, $slot_name ) = @_;
132 *$instance->{$slot_name};
133 }
134
135 This level of indirection probably makes our instance class slower than
136 the default. However, when attribute access is inlined, this lookup
137 will be cached:
138
139 sub inline_slot_access {
140 my ( $self, $instance, $slot_name ) = @_;
141 return '*{' . $instance . '}->{' . $slot_name . '}';
142 }
143
144 The code snippet that the "inline_slot_access" method returns will get
145 "eval"'d once per attribute.
146
147 Finally, we use this meta-instance in our "MyApp::User" class:
148
149 Moose::Util::MetaRole::apply_metaroles(
150 for => __PACKAGE__,
151 class_metaroles => {
152 instance => ['My::Meta::Instance'],
153 },
154 );
155
156 We actually don't recommend the use of Moose::Util::MetaRole directly
157 in your class in most cases. Typically, this would be provided by a
158 Moose::Exporter-based module which handles applying the role for you.
159
161 This recipe shows how to create your own meta-instance class. It's
162 unlikely that you'll need to do this yourself, but it's interesting to
163 take a peek at how Moose works under the hood.
164
166 There are a few meta-instance class extensions on CPAN:
167
168 • MooseX::Singleton
169
170 This module extends the instance class in order to ensure that the
171 object is a singleton. The instance it uses is still a blessed hash
172 reference.
173
174 • MooseX::GlobRef
175
176 This module makes the instance a blessed glob reference. This lets
177 you use a handle as an object instance.
178
180 • Stevan Little <stevan@cpan.org>
181
182 • Dave Rolsky <autarch@urth.org>
183
184 • Jesse Luehrs <doy@cpan.org>
185
186 • Shawn M Moore <sartak@cpan.org>
187
188 • יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
189
190 • Karen Etheridge <ether@cpan.org>
191
192 • Florian Ragwitz <rafl@debian.org>
193
194 • Hans Dieter Pearcey <hdp@cpan.org>
195
196 • Chris Prather <chris@prather.org>
197
198 • Matt S Trout <mstrout@cpan.org>
199
201 This software is copyright (c) 2006 by Infinity Interactive, Inc.
202
203 This is free software; you can redistribute it and/or modify it under
204 the same terms as the Perl 5 programming language system itself.
205
206
207
208perl v5.36.0 Moose::2C0o2o2k-b0o7o-k2:2:Meta::GlobRef_InstanceMetaclass(3)