File Coverage

blib/lib/MooseX/TraitFor/Meta/Class/BetterAnonClassNames.pm
Criterion Covered Total %
statement 18 18 100.0
branch 1 2 50.0
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 27 96.3


line stmt bran cond sub pod time code
1             #
2             # This file is part of MooseX-TraitFor-Meta-Class-BetterAnonClassNames
3             #
4             # This software is Copyright (c) 2014 by Chris Weyl.
5             #
6             # This is free software, licensed under:
7             #
8             # The GNU Lesser General Public License, Version 2.1, February 1999
9             #
10             package MooseX::TraitFor::Meta::Class::BetterAnonClassNames;
11             our $AUTHORITY = 'cpan:RSRCHBOY';
12             # git description: 0.002002-6-gfc980d7
13             $MooseX::TraitFor::Meta::Class::BetterAnonClassNames::VERSION = '0.002003';
14              
15             # ABSTRACT: Metaclass trait to *attempt* to demystify generated anonymous class names
16              
17 2     2   559157 use Moose::Role;
  2         109538  
  2         7  
18 2     2   8472 use namespace::autoclean;
  2         12257  
  2         6  
19 2     2   1192 use autobox::Core;
  2         29070  
  2         12  
20              
21 2     2   747 use Moose::Exporter;
  2         4  
  2         20  
22              
23             Moose::Exporter->setup_import_methods(
24             trait_aliases => [ __PACKAGE__ ],
25             );
26              
27              
28             has is_anon => (is => 'ro', isa => 'Bool', default => 0);
29              
30              
31             has anon_package_prefix => (
32             is => 'ro',
33             isa => 'Str',
34             builder => '_build_anon_package_prefix',
35             );
36              
37 1     1   4718 sub _build_anon_package_prefix { Moose::Meta::Class->_anon_package_prefix }
38              
39              
40 1     1   5 sub _anon_package_middle { '::__ANON__::SERIAL::' }
41              
42              
43             sub _anon_package_prefix {
44 3     3   35 my $thing = shift @_;
45              
46 3 50       145 my $prefix = blessed $thing
47             ? $thing->anon_package_prefix
48             : Moose::Meta::Class->_anon_package_prefix
49             ;
50              
51 3         27 my @caller = caller 1;
52             ### @caller
53             ### $prefix
54 3         12 return $prefix;
55             }
56              
57              
58             around create => sub {
59             my ($orig, $self) = (shift, shift);
60             my @args = @_;
61              
62             unshift @args, 'package'
63             if @args % 2;
64             my %opts = @args;
65              
66             return $self->$orig(%opts)
67             unless $opts{is_anon} && $opts{anon_package_prefix};
68              
69             ### old anon package name: $opts{package}
70             my $serial = $opts{package}->split(qr/::/)->[-1]; #at(-1); #tail(1);
71             $opts{package} = $opts{anon_package_prefix} . $serial;
72              
73             ### new anon package name: $opts{package}
74             ### %opts
75             return $self->$orig(%opts);
76             };
77              
78              
79             around create_anon_class => sub {
80             my ($orig, $class) = (shift, shift);
81             my %opts = @_;
82              
83             # we're going to need some additional logic here to make sure that our
84             # prefixes make sense; e.g. if we're an anon descendent of an anon class,
85             # we should just use our parent's prefix.
86              
87             $opts{is_anon} = 1;
88              
89             my $superclasses = $opts{superclasses} || [];
90              
91             # don't bother doing anything else if we don't have anything to add
92             return $class->$orig(%opts)
93             if exists $opts{anon_package_prefix};
94             return $class->$orig(%opts)
95             unless @$superclasses && @$superclasses == 1;
96              
97             # XXX ::class_of?
98             my $sc = $superclasses->[0]->meta;
99              
100             #my $prefix
101             $opts{anon_package_prefix}
102             = $sc->is_anon
103             ? $sc->_anon_package_prefix
104             : $superclasses->[0] . $class->_anon_package_middle
105             ;
106              
107             # basically: if we have no superclasses, live with the default prefix; if
108             # we have a superclass and it's anon, use it's anon prefix; if we have a
109             # superclass and it's not anon, make a new prefix out of it
110             #
111             # cases where we have 2+ superclasses aren't handled right now; we use the
112             # Moose::Meta::Class::_anon_package_prefix() for those
113             #
114             # if we're passed in 'anon_package_prefix', then just use that.
115              
116             return $class->$orig(%opts);
117             };
118              
119             !!42;
120              
121             __END__
122              
123             =pod
124              
125             =encoding UTF-8
126              
127             =for :stopwords Chris Weyl
128              
129             =head1 NAME
130              
131             MooseX::TraitFor::Meta::Class::BetterAnonClassNames - Metaclass trait to *attempt* to demystify generated anonymous class names
132              
133             =head1 VERSION
134              
135             This document describes version 0.002003 of MooseX::TraitFor::Meta::Class::BetterAnonClassNames - released March 23, 2017 as part of MooseX-TraitFor-Meta-Class-BetterAnonClassNames.
136              
137             =head1 ATTRIBUTES
138              
139             =head2 is_anon
140              
141             Read-only, L<Boolean|Moose::Util::TypeConstraints/Default Type Constraints>,
142             default: false.
143              
144             Provides an attribute in the place of L<Class::MOP::Package/is_anon>.
145              
146             =head2 anon_package_prefix
147              
148             Read-only, L<String|Moose::Util::TypeConstraints/Default Type Constraints>
149              
150             =head1 METHODS
151              
152             =head2 _build_anon_package_prefix
153              
154             Builder method for the L</anon_package_prefix> attribute.
155              
156             =head2 _anon_package_middle
157              
158             Defines what the "middle" of our anonymous package names is; provided for ease
159             of overriding and hardcoded to:
160              
161             ::__ANON__::SERIAL::
162              
163             =head2 _anon_package_prefix
164              
165             Returns the full prefix used to generate anonymous package names; if called
166             on an instance then returns a sensible prefix (generally class name)
167             stashed in L</anon_package_prefix>; otherwise returns the result of a call
168             to L<Moose::Meta::Class/_anon_package_prefix>.
169              
170             =head2 create
171              
172             Set the package name to a nicer anonymous class name if is_anon is passed
173             and true and anon_package_prefix is passed and a non-empty string.
174              
175             =head2 create_anon_class
176              
177             Create an anonymous class, as via L<Moose::Meta::Class/create_anon_class>,
178             but with a kinder, gentler package name -- if possible.
179              
180             =head1 SUMMARY
181              
182             You really want to be looking at L<MooseX::Util/with_traits>.
183              
184             =head1 TRAIT ALIASES
185              
186             =head2 BetterAnonClassNames
187              
188             Resolves out to the full name of this trait.
189              
190             =head1 SEE ALSO
191              
192             Please see those modules/websites for more information related to this module.
193              
194             =over 4
195              
196             =item *
197              
198             L<MooseX::Util>
199              
200             =back
201              
202             =head1 BUGS
203              
204             Please report any bugs or feature requests on the bugtracker website
205             L<https://github.com/RsrchBoy/moosex-traitfor-meta-class-betteranonclassnames/issues>
206              
207             When submitting a bug or request, please include a test-file or a
208             patch to an existing test-file that illustrates the bug or desired
209             feature.
210              
211             =head1 AUTHOR
212              
213             Chris Weyl <cweyl@alumni.drew.edu>
214              
215             =head1 COPYRIGHT AND LICENSE
216              
217             This software is Copyright (c) 2014 by Chris Weyl.
218              
219             This is free software, licensed under:
220              
221             The GNU Lesser General Public License, Version 2.1, February 1999
222              
223             =cut