Improve text of ro/wo violation exceptions
[p5sagit/Class-Accessor-Grouped.git] / lib / Class / Accessor / Grouped.pm
1 package Class::Accessor::Grouped;
2 use strict;
3 use warnings;
4 use Carp ();
5 use Scalar::Util ();
6 use Module::Runtime ();
7
8 BEGIN {
9   # use M::R to work around the 5.8 require bugs
10   if ($] < 5.009_005) {
11     Module::Runtime::require_module('MRO::Compat');
12   }
13   else {
14     require mro;
15   }
16 }
17
18 our $VERSION = '0.10006';
19 $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
20
21 # when changing minimum version don't forget to adjust Makefile.PL as well
22 our $__minimum_xsa_version;
23 BEGIN { $__minimum_xsa_version = '1.13' }
24
25 our $USE_XS;
26 # the unless defined is here so that we can override the value
27 # before require/use, *regardless* of the state of $ENV{CAG_USE_XS}
28 $USE_XS = $ENV{CAG_USE_XS}
29   unless defined $USE_XS;
30
31 BEGIN {
32   package # hide from PAUSE
33     __CAG_ENV__;
34
35   die "Huh?! No minimum C::XSA version?!\n"
36     unless $__minimum_xsa_version;
37
38   local $@;
39   require constant;
40
41   # individual (one const at a time) imports so we are 5.6.2 compatible
42   # if we can - why not ;)
43   constant->import( NO_SUBNAME => eval {
44     Module::Runtime::require_module('Sub::Name')
45   } ? 0 : "$@" );
46
47   constant->import( NO_CXSA => ( !NO_SUBNAME() and eval {
48     Module::Runtime::use_module('Class::XSAccessor' => $__minimum_xsa_version)
49   } ) ? 0 : "$@" );
50
51   constant->import( BROKEN_GOTO => ($] < '5.008009') ? 1 : 0 );
52
53   constant->import( UNSTABLE_DOLLARAT => ($] < '5.013002') ? 1 : 0 );
54
55   constant->import( TRACK_UNDEFER_FAIL => (
56     $INC{'Test/Builder.pm'} || $INC{'Test/Builder2.pm'}
57       and
58     $0 =~ m|^ x?t / .+ \.t $|x
59   ) ? 1 : 0 );
60 }
61
62 # Yes this method is undocumented
63 # Yes it should be a private coderef like all the rest at the end of this file
64 # No we can't do that (yet) because the DBIC-CDBI compat layer overrides it
65 # %$*@!?&!&#*$!!!
66 sub _mk_group_accessors {
67   my($self, $maker, $group, @fields) = @_;
68   my $class = length (ref ($self) ) ? ref ($self) : $self;
69
70   no strict 'refs';
71   no warnings 'redefine';
72
73   # So we don't have to do lots of lookups inside the loop.
74   $maker = $self->can($maker) unless ref $maker;
75
76   for (@fields) {
77
78     my ($name, $field) = (ref $_) ? (@$_) : ($_, $_);
79
80     for (qw/DESTROY AUTOLOAD CLONE/) {
81       Carp::carp("Having a data accessor named '$name' in '$class' is unwise.")
82         if $name eq $_;
83     }
84
85     my $alias = "_${name}_accessor";
86
87     for ($name, $alias) {
88
89       # the maker may elect to not return anything, meaning it already
90       # installed the coderef for us (e.g. lack of Sub::Name)
91       my $cref = $self->$maker($group, $field, $_)
92         or next;
93
94       my $fq_meth = "${class}::$_";
95
96       *$fq_meth = Sub::Name::subname($fq_meth, $cref);
97         #unless defined &{$class."\:\:$field"}
98     }
99   }
100 };
101
102 # coderef is setup at the end for clarity
103 my $gen_accessor;
104
105 =head1 NAME
106
107 Class::Accessor::Grouped - Lets you build groups of accessors
108
109 =head1 SYNOPSIS
110
111  use base 'Class::Accessor::Grouped';
112
113  # make basic accessors for objects
114  __PACKAGE__->mk_group_accessors(simple => qw(id name email));
115
116  # make accessor that works for objects and classes
117  __PACKAGE__->mk_group_accessors(inherited => 'awesome_level');
118
119 =head1 DESCRIPTION
120
121 This class lets you build groups of accessors that will call different
122 getters and setters.
123
124 =head1 METHODS
125
126 =head2 mk_group_accessors
127
128  __PACKAGE__->mk_group_accessors(simple => 'hair_length', [ hair_color => 'hc' ]);
129
130 =over 4
131
132 =item Arguments: $group, @fieldspec
133
134 Returns: none
135
136 =back
137
138 Creates a set of accessors in a given group.
139
140 $group is the name of the accessor group for the generated accessors; they
141 will call get_$group($field) on get and set_$group($field, $value) on set.
142
143 If you want to mimic Class::Accessor's mk_accessors $group has to be 'simple'
144 to tell Class::Accessor::Grouped to use its own get_simple and set_simple
145 methods.
146
147 @fieldspec is a list of field/accessor names; if a fieldspec is a scalar
148 this is used as both field and accessor name, if a listref it is expected to
149 be of the form [ $accessor, $field ].
150
151 =cut
152
153 sub mk_group_accessors {
154   my ($self, $group, @fields) = @_;
155
156   $self->_mk_group_accessors('make_group_accessor', $group, @fields);
157   return;
158 }
159
160 =head2 mk_group_ro_accessors
161
162  __PACKAGE__->mk_group_ro_accessors(simple => 'birthdate', [ social_security_number => 'ssn' ]);
163
164 =over 4
165
166 =item Arguments: $group, @fieldspec
167
168 Returns: none
169
170 =back
171
172 Creates a set of read only accessors in a given group. Identical to
173 L</mk_group_accessors> but accessors will throw an error if passed a value
174 rather than setting the value.
175
176 =cut
177
178 sub mk_group_ro_accessors {
179   my($self, $group, @fields) = @_;
180
181   $self->_mk_group_accessors('make_group_ro_accessor', $group, @fields);
182   return;
183 }
184
185 =head2 mk_group_wo_accessors
186
187  __PACKAGE__->mk_group_wo_accessors(simple => 'lie', [ subject => 'subj' ]);
188
189 =over 4
190
191 =item Arguments: $group, @fieldspec
192
193 Returns: none
194
195 =back
196
197 Creates a set of write only accessors in a given group. Identical to
198 L</mk_group_accessors> but accessors will throw an error if not passed a
199 value rather than getting the value.
200
201 =cut
202
203 sub mk_group_wo_accessors {
204   my($self, $group, @fields) = @_;
205
206   $self->_mk_group_accessors('make_group_wo_accessor', $group, @fields);
207   return;
208 }
209
210 =head2 get_simple
211
212 =over 4
213
214 =item Arguments: $field
215
216 Returns: $value
217
218 =back
219
220 Simple getter for hash-based objects which returns the value for the field
221 name passed as an argument.
222
223 =cut
224
225 sub get_simple {
226   $_[0]->{$_[1]};
227 }
228
229 =head2 set_simple
230
231 =over 4
232
233 =item Arguments: $field, $new_value
234
235 Returns: $new_value
236
237 =back
238
239 Simple setter for hash-based objects which sets and then returns the value
240 for the field name passed as an argument.
241
242 =cut
243
244 sub set_simple {
245   $_[0]->{$_[1]} = $_[2];
246 }
247
248
249 =head2 get_inherited
250
251 =over 4
252
253 =item Arguments: $field
254
255 Returns: $value
256
257 =back
258
259 Simple getter for Classes and hash-based objects which returns the value for
260 the field name passed as an argument. This behaves much like
261 L<Class::Data::Accessor> where the field can be set in a base class,
262 inherited and changed in subclasses, and inherited and changed for object
263 instances.
264
265 =cut
266
267 sub get_inherited {
268   if ( length (ref ($_[0]) ) ) {
269     if (Scalar::Util::reftype $_[0] eq 'HASH') {
270       return $_[0]->{$_[1]} if exists $_[0]->{$_[1]};
271       # everything in @_ is aliased, an assignment won't work
272       splice @_, 0, 1, ref($_[0]);
273     }
274     else {
275       Carp::croak('Cannot get inherited value on an object instance that is not hash-based');
276     }
277   }
278
279   # if we got this far there is nothing in the instance
280   # OR this is a class call
281   # in any case $_[0] contains the class name (see splice above)
282   no strict 'refs';
283   no warnings 'uninitialized';
284
285   my $cag_slot = '::__cag_'. $_[1];
286   return ${$_[0].$cag_slot} if defined(${$_[0].$cag_slot});
287
288   do { return ${$_.$cag_slot} if defined(${$_.$cag_slot}) }
289     for $_[0]->get_super_paths;
290
291   return undef;
292 }
293
294 =head2 set_inherited
295
296 =over 4
297
298 =item Arguments: $field, $new_value
299
300 Returns: $new_value
301
302 =back
303
304 Simple setter for Classes and hash-based objects which sets and then returns
305 the value for the field name passed as an argument. When called on a hash-based
306 object it will set the appropriate hash key value. When called on a class, it
307 will set a class level variable.
308
309 B<Note:>: This method will die if you try to set an object variable on a non
310 hash-based object.
311
312 =cut
313
314 sub set_inherited {
315   if (length (ref ($_[0]) ) ) {
316     if (Scalar::Util::reftype $_[0] eq 'HASH') {
317       return $_[0]->{$_[1]} = $_[2];
318     } else {
319       Carp::croak('Cannot set inherited value on an object instance that is not hash-based');
320     };
321   }
322
323   no strict 'refs';
324   ${$_[0].'::__cag_'.$_[1]} = $_[2];
325 }
326
327 =head2 get_component_class
328
329 =over 4
330
331 =item Arguments: $field
332
333 Returns: $value
334
335 =back
336
337 Gets the value of the specified component class.
338
339  __PACKAGE__->mk_group_accessors('component_class' => 'result_class');
340
341  $self->result_class->method();
342
343  ## same as
344  $self->get_component_class('result_class')->method();
345
346 =cut
347
348 sub get_component_class {
349   $_[0]->get_inherited($_[1]);
350 };
351
352 =head2 set_component_class
353
354 =over 4
355
356 =item Arguments: $field, $class
357
358 Returns: $new_value
359
360 =back
361
362 Inherited accessor that automatically loads the specified class before setting
363 it. This method will die if the specified class could not be loaded.
364
365  __PACKAGE__->mk_group_accessors('component_class' => 'result_class');
366  __PACKAGE__->result_class('MyClass');
367
368  $self->result_class->method();
369
370 =cut
371
372 sub set_component_class {
373   if (defined $_[2] and length $_[2]) {
374     # disable warnings, and prevent $_ being eaten away by a behind-the-scenes
375     # module loading
376     local ($^W, $_);
377
378     if (__CAG_ENV__::UNSTABLE_DOLLARAT) {
379       my $err;
380       {
381         local $@;
382         eval { Module::Runtime::use_package_optimistically($_[2]) }
383           or $err = $@;
384       }
385       Carp::croak("Could not load $_[1] '$_[2]': $err") if defined $err;
386
387     }
388     else {
389       eval { Module::Runtime::use_package_optimistically($_[2]) }
390         or Carp::croak("Could not load $_[1] '$_[2]': $@");
391     }
392   };
393
394   $_[0]->set_inherited($_[1], $_[2]);
395 };
396
397 =head1 INTERNAL METHODS
398
399 These methods are documented for clarity, but are never meant to be called
400 directly, and are not really meant for overriding either.
401
402 =head2 get_super_paths
403
404 Returns a list of 'parent' or 'super' class names that the current class
405 inherited from. This is what drives the traversal done by L</get_inherited>.
406
407 =cut
408
409 sub get_super_paths {
410   # get_linear_isa returns the class itself as the 1st element
411   # use @_ as a pre-allocated scratch array
412   (undef, @_) = @{mro::get_linear_isa( length( ref($_[0]) ) ? ref($_[0]) : $_[0] )};
413   @_;
414 };
415
416 =head2 make_group_accessor
417
418  __PACKAGE__->make_group_accessor('simple', 'hair_length', 'hair_length');
419  __PACKAGE__->make_group_accessor('simple', 'hc', 'hair_color');
420
421 =over 4
422
423 =item Arguments: $group, $field, $accessor
424
425 Returns: \&accessor_coderef ?
426
427 =back
428
429 Called by mk_group_accessors for each entry in @fieldspec. Either returns
430 a coderef which will be installed at C<&__PACKAGE__::$accessor>, or returns
431 C<undef> if it elects to install the coderef on its own.
432
433 =cut
434
435 sub make_group_accessor { $gen_accessor->('rw', @_) }
436
437 =head2 make_group_ro_accessor
438
439  __PACKAGE__->make_group_ro_accessor('simple', 'birthdate', 'birthdate');
440  __PACKAGE__->make_group_ro_accessor('simple', 'ssn', 'social_security_number');
441
442 =over 4
443
444 =item Arguments: $group, $field, $accessor
445
446 Returns: \&accessor_coderef ?
447
448 =back
449
450 Called by mk_group_ro_accessors for each entry in @fieldspec. Either returns
451 a coderef which will be installed at C<&__PACKAGE__::$accessor>, or returns
452 C<undef> if it elects to install the coderef on its own.
453
454 =cut
455
456 sub make_group_ro_accessor { $gen_accessor->('ro', @_) }
457
458 =head2 make_group_wo_accessor
459
460  __PACKAGE__->make_group_wo_accessor('simple', 'lie', 'lie');
461  __PACKAGE__->make_group_wo_accessor('simple', 'subj', 'subject');
462
463 =over 4
464
465 =item Arguments: $group, $field, $accessor
466
467 Returns: \&accessor_coderef ?
468
469 =back
470
471 Called by mk_group_wo_accessors for each entry in @fieldspec. Either returns
472 a coderef which will be installed at C<&__PACKAGE__::$accessor>, or returns
473 C<undef> if it elects to install the coderef on its own.
474
475 =cut
476
477 sub make_group_wo_accessor { $gen_accessor->('wo', @_) }
478
479
480 =head1 PERFORMANCE
481
482 To provide total flexibility L<Class::Accessor::Grouped> calls methods
483 internally while performing get/set actions, which makes it noticeably
484 slower than similar modules. To compensate, this module will automatically
485 use the insanely fast L<Class::XSAccessor> to generate the C<simple>-group
486 accessors if this module is available on your system.
487
488 =head2 Benchmark
489
490 This is the result of a set/get/set loop benchmark on perl 5.12.1 with
491 thread support, showcasing most popular accessor builders: L<Moose>, L<Mouse>,
492 L<Moo>, L<CAF|Class::Accessor::Fast>, L<CAF_XS|Class::Accessor::Fast::XS>,
493 L<XSA|Class::XSAccessor>, and L<CAF_XSA|Class::XSAccessor::Compat>:
494
495            Rate  CAG moOse  CAF moUse  moo HANDMADE CAF_XS moUse_XS moo_XS CAF_XSA  XSA CAG_XS
496  CAG      169/s   --  -21% -24%  -32% -32%     -34%   -59%     -63%   -67%    -67% -67%   -67%
497  moOse    215/s  27%    --  -3%  -13% -13%     -15%   -48%     -53%   -58%    -58% -58%   -58%
498  CAF      222/s  31%    3%   --  -10% -10%     -13%   -46%     -52%   -57%    -57% -57%   -57%
499  moUse    248/s  46%   15%  11%    --  -0%      -3%   -40%     -46%   -52%    -52% -52%   -52%
500  moo      248/s  46%   15%  11%    0%   --      -3%   -40%     -46%   -52%    -52% -52%   -52%
501  HANDMADE 255/s  50%   18%  14%    3%   3%       --   -38%     -45%   -50%    -51% -51%   -51%
502  CAF_XS   411/s 143%   91%  85%   66%  66%      61%     --     -11%   -20%    -20% -21%   -21%
503  moUse_XS 461/s 172%  114% 107%   86%  86%      81%    12%       --   -10%    -11% -11%   -11%
504  moo_XS   514/s 204%  139% 131%  107% 107%     102%    25%      12%     --     -0%  -1%    -1%
505  CAF_XSA  516/s 205%  140% 132%  108% 108%     103%    26%      12%     0%      --  -0%    -0%
506  XSA      519/s 206%  141% 133%  109% 109%     104%    26%      13%     1%      0%   --    -0%
507  CAG_XS   519/s 206%  141% 133%  109% 109%     104%    26%      13%     1%      0%   0%     --
508
509 Benchmark program is available in the root of the
510 L<repository|http://search.cpan.org/dist/Class-Accessor-Grouped/>:
511
512 =head2 Notes on Class::XSAccessor
513
514 You can force (or disable) the use of L<Class::XSAccessor> before creating a
515 particular C<simple> accessor by either manipulating the global variable
516 C<$Class::Accessor::Grouped::USE_XS> to true or false (preferably with
517 L<localization|perlfunc/local>, or you can do so before runtime via the
518 C<CAG_USE_XS> environment variable.
519
520 Since L<Class::XSAccessor> has no knowledge of L</get_simple> and
521 L</set_simple> this module does its best to detect if you are overriding
522 one of these methods and will fall back to using the perl version of the
523 accessor in order to maintain consistency. However be aware that if you
524 enable use of C<Class::XSAccessor> (automatically or explicitly), create
525 an object, invoke a simple accessor on that object, and B<then> manipulate
526 the symbol table to install a C<get/set_simple> override - you get to keep
527 all the pieces.
528
529 =head1 AUTHORS
530
531 Matt S. Trout <mst@shadowcatsystems.co.uk>
532
533 Christopher H. Laco <claco@chrislaco.com>
534
535 =head1 CONTRIBUTORS
536
537 Caelum: Rafael Kitover <rkitover@cpan.org>
538
539 frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
540
541 groditi: Guillermo Roditi <groditi@cpan.org>
542
543 Jason Plum <jason.plum@bmmsi.com>
544
545 ribasushi: Peter Rabbitson <ribasushi@cpan.org>
546
547
548 =head1 COPYRIGHT & LICENSE
549
550 Copyright (c) 2006-2010 Matt S. Trout <mst@shadowcatsystems.co.uk>
551
552 This program is free software; you can redistribute it and/or modify
553 it under the same terms as perl itself.
554
555 =cut
556
557 ########################################################################
558 ########################################################################
559 ########################################################################
560 #
561 # Here be many angry dragons
562 # (all code is in private coderefs since everything inherits CAG)
563 #
564 ########################################################################
565 ########################################################################
566
567 # Autodetect unless flag supplied
568 my $xsa_autodetected;
569 if (! defined $USE_XS) {
570   $USE_XS = __CAG_ENV__::NO_CXSA ? 0 : 1;
571   $xsa_autodetected++;
572 }
573
574 my $perlstring;
575 if ($] < '5.008') {
576   require Data::Dumper;
577   my $d = Data::Dumper->new([])->Indent(0)->Purity(0)->Pad('')->Useqq(1)->Terse(1)->Freezer('')->Toaster('');
578   $perlstring = sub { $d->Values([shift])->Dump };
579 }
580 else {
581   require B;
582   $perlstring = \&B::perlstring;
583 }
584
585
586 my $maker_templates = {
587   rw => {
588     xs_call => 'accessors',
589     pp_code => sub {
590       # my ($group, $fieldname) = @_;
591       my $quoted_fieldname = $perlstring->($_[1]);
592       sprintf <<'EOS', ($_[0], $quoted_fieldname) x 2;
593
594 @_ > 1
595   ? shift->set_%s(%s, @_)
596   : shift->get_%s(%s)
597 EOS
598
599     },
600   },
601   ro => {
602     xs_call => 'getters',
603     pp_code => sub {
604       # my ($group, $fieldname) = @_;
605       my $quoted_fieldname = $perlstring->($_[1]);
606       sprintf  <<'EOS', $_[0], $quoted_fieldname;
607
608 @_ > 1
609   ? do {
610     my ($meth) = (caller(0))[3] =~ /([^\:]+)$/;
611     my $class = length( ref($_[0]) ) ? ref($_[0]) : $_[0];
612     Carp::croak(
613       "'$meth' cannot alter its value (read-only attribute of class $class)"
614     );
615   }
616   : shift->get_%s(%s)
617 EOS
618
619     },
620   },
621   wo => {
622     xs_call => 'setters',
623     pp_code => sub {
624       # my ($group, $fieldname) = @_;
625       my $quoted_fieldname = $perlstring->($_[1]);
626       sprintf  <<'EOS', $_[0], $quoted_fieldname;
627
628 @_ > 1
629   ? shift->set_%s(%s, @_)
630   : do {
631     my ($meth) = (caller(0))[3] =~ /([^\:]+)$/;
632     my $class = length( ref($_[0]) ) ? ref($_[0]) : $_[0];
633     Carp::croak(
634       "'$meth' cannot access its value (write-only attribute of class $class)"
635     );
636   }
637 EOS
638
639     },
640   },
641 };
642
643
644 my ($accessor_maker_cache, $no_xsa_warned_classes);
645
646 # can't use pkg_gen to track this stuff, as it doesn't
647 # detect superclass mucking
648 my $original_simple_getter = __PACKAGE__->can ('get_simple');
649 my $original_simple_setter = __PACKAGE__->can ('set_simple');
650
651 # Note!!! Unusual signature
652 $gen_accessor = sub {
653   my ($type, $class, $group, $field, $methname) = @_;
654   $class = ref $class if length ref $class;
655
656   # When installing an XSA simple accessor, we need to make sure we are not
657   # short-circuiting a (compile or runtime) get_simple/set_simple override.
658   # What we do here is install a lazy first-access check, which will decide
659   # the ultimate coderef being placed in the accessor slot
660   #
661   # Also note that the *original* class will always retain this shim, as
662   # different branches inheriting from it may have different overrides.
663   # Thus the final method (properly labeled and all) is installed in the
664   # calling-package's namespace
665   if ($USE_XS and $group eq 'simple') {
666     die sprintf( "Class::XSAccessor requested but not available:\n%s\n", __CAG_ENV__::NO_CXSA )
667       if __CAG_ENV__::NO_CXSA;
668
669     my ($expected_cref, $cached_implementation);
670     my $ret = $expected_cref = sub {
671       my $current_class = length (ref ($_[0] ) ) ? ref ($_[0]) : $_[0];
672
673       # $cached_implementation will be set only if the shim got
674       # 'around'ed, in which case it is handy to avoid re-running
675       # this block over and over again
676       my $resolved_implementation = $cached_implementation->{$current_class} || do {
677         if (
678           ($current_class->can('get_simple')||0) == $original_simple_getter
679             &&
680           ($current_class->can('set_simple')||0) == $original_simple_setter
681         ) {
682           # nothing has changed, might as well use the XS crefs
683           #
684           # note that by the time this code executes, we already have
685           # *objects* (since XSA works on 'simple' only by definition).
686           # If someone is mucking with the symbol table *after* there
687           # are some objects already - look! many, shiny pieces! :)
688           #
689           # The weird breeder thingy is because XSA does not have an
690           # interface returning *just* a coderef, without installing it
691           # anywhere :(
692           Class::XSAccessor->import(
693             replace => 1,
694             class => '__CAG__XSA__BREEDER__',
695             $maker_templates->{$type}{xs_call} => {
696               $methname => $field,
697             },
698           );
699           __CAG__XSA__BREEDER__->can($methname);
700         }
701         else {
702           if (! $xsa_autodetected and ! $no_xsa_warned_classes->{$current_class}++) {
703             # not using Carp since the line where this happens doesn't mean much
704             warn 'Explicitly requested use of Class::XSAccessor disabled for objects of class '
705               . "'$current_class' inheriting from '$class' due to an overriden get_simple and/or "
706               . "set_simple\n";
707           }
708
709           do {
710             # that's faster than local
711             $USE_XS = 0;
712             my $c = $gen_accessor->($type, $class, 'simple', $field, $methname);
713             $USE_XS = 1;
714             $c;
715           };
716         }
717       };
718
719       # if after this shim was created someone wrapped it with an 'around',
720       # we can not blindly reinstall the method slot - we will destroy the
721       # wrapper. Silently chain execution further...
722       if ( !$expected_cref or $expected_cref != ($current_class->can($methname)||0) ) {
723
724         # there is no point in re-determining it on every subsequent call,
725         # just store for future reference
726         $cached_implementation->{$current_class} ||= $resolved_implementation;
727
728         # older perls segfault if the cref behind the goto throws
729         # http://rt.perl.org/rt3/Public/Bug/Display.html?id=35878
730         return $resolved_implementation->(@_) if __CAG_ENV__::BROKEN_GOTO;
731
732         goto $resolved_implementation;
733       }
734
735       if (__CAG_ENV__::TRACK_UNDEFER_FAIL) {
736         my $deferred_calls_seen = do {
737           no strict 'refs';
738           \%{"${current_class}::__cag_deferred_xs_shim_invocations"}
739         };
740         my @cframe = caller(0);
741         if (my $already_seen = $deferred_calls_seen->{$cframe[3]}) {
742           Carp::carp (
743             "Deferred version of method $cframe[3] invoked more than once (originally "
744           . "invoked at $already_seen). This is a strong indication your code has "
745           . 'cached the original ->can derived method coderef, and is using it instead '
746           . 'of the proper method re-lookup, causing performance regressions'
747           );
748         }
749         else {
750           $deferred_calls_seen->{$cframe[3]} = "$cframe[1] line $cframe[2]";
751         }
752       }
753
754       # install the resolved implementation into the code slot so we do not
755       # come here anymore (hopefully)
756       # since XSAccessor was available - so is Sub::Name
757       {
758         no strict 'refs';
759         no warnings 'redefine';
760
761         my $fq_name = "${current_class}::${methname}";
762         *$fq_name = Sub::Name::subname($fq_name, $resolved_implementation);
763
764         # need to update what the shim expects too *in case* its
765         # ->can was cached for some moronic reason
766         $expected_cref = $resolved_implementation;
767         Scalar::Util::weaken($expected_cref);
768       }
769
770       # older perls segfault if the cref behind the goto throws
771       # http://rt.perl.org/rt3/Public/Bug/Display.html?id=35878
772       return $resolved_implementation->(@_) if __CAG_ENV__::BROKEN_GOTO;
773
774       goto $resolved_implementation;
775     };
776
777     Scalar::Util::weaken($expected_cref); # to break the self-reference
778     $ret;
779   }
780
781   # no Sub::Name - just install the coderefs directly (compiling every time)
782   elsif (__CAG_ENV__::NO_SUBNAME) {
783     my $src = $accessor_maker_cache->{source}{$type}{$group}{$field} ||=
784       $maker_templates->{$type}{pp_code}->($group, $field);
785
786     no warnings 'redefine';
787     local $@ if __CAG_ENV__::UNSTABLE_DOLLARAT;
788     eval "sub ${class}::${methname} { $src }";
789
790     undef;  # so that no further attempt will be made to install anything
791   }
792
793   # a coderef generator with a variable pad (returns a fresh cref on every invocation)
794   else {
795     ($accessor_maker_cache->{pp}{$type}{$group}{$field} ||= do {
796       my $src = $accessor_maker_cache->{source}{$type}{$group}{$field} ||=
797         $maker_templates->{$type}{pp_code}->($group, $field);
798
799       local $@ if __CAG_ENV__::UNSTABLE_DOLLARAT;
800       eval "sub { my \$dummy; sub { \$dummy if 0; $src } }" or die $@;
801     })->()
802   }
803 };
804
805 1;