File Coverage

blib/lib/MooseX/TraitFor/Meta/Class/BetterAnonClassNames.pm
Criterion Covered Total %
statement 15 15 100.0
branch 1 2 50.0
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 23 95.6


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.002001-6-gd0c33f9
13             $MooseX::TraitFor::Meta::Class::BetterAnonClassNames::VERSION = '0.002002';
14              
15             # ABSTRACT: Metaclass trait to *attempt* to demystify generated anonymous class names
16              
17 1     1   287559 use Moose::Role;
  1         123513  
  1         5  
18 1     1   4873 use namespace::autoclean;
  1         1178  
  1         5  
19 1     1   795 use autobox::Core;
  1         12871  
  1         6  
20              
21              
22             has is_anon => (is => 'ro', isa => 'Bool', default => 0);
23              
24              
25             has anon_package_prefix => (
26             is => 'ro',
27             isa => 'Str',
28             builder => '_build_anon_package_prefix',
29             );
30              
31 1     1   2810 sub _build_anon_package_prefix { Moose::Meta::Class->_anon_package_prefix }
32              
33              
34 1     1   3 sub _anon_package_middle { '::__ANON__::SERIAL::' }
35              
36              
37             sub _anon_package_prefix {
38 3     3   35 my $thing = shift @_;
39              
40 3 50       164 my $prefix = blessed $thing
41             ? $thing->anon_package_prefix
42             : Moose::Meta::Class->_anon_package_prefix
43             ;
44              
45 3         22 my @caller = caller 1;
46             ### @caller
47             ### $prefix
48 3         11 return $prefix;
49             }
50              
51              
52             around create => sub {
53             my ($orig, $self) = (shift, shift);
54             my @args = @_;
55              
56             unshift @args, 'package'
57             if @args % 2;
58             my %opts = @args;
59              
60             return $self->$orig(%opts)
61             unless $opts{is_anon} && $opts{anon_package_prefix};
62              
63             ### old anon package name: $opts{package}
64             my $serial = $opts{package}->split(qr/::/)->[-1]; #at(-1); #tail(1);
65             $opts{package} = $opts{anon_package_prefix} . $serial;
66              
67             ### new anon package name: $opts{package}
68             ### %opts
69             return $self->$orig(%opts);
70             };
71              
72              
73             around create_anon_class => sub {
74             my ($orig, $class) = (shift, shift);
75             my %opts = @_;
76              
77             # we're going to need some additional logic here to make sure that our
78             # prefixes make sense; e.g. if we're an anon descendent of an anon class,
79             # we should just use our parent's prefix.
80              
81             $opts{is_anon} = 1;
82              
83             my $superclasses = $opts{superclasses} || [];
84              
85             # don't bother doing anything else if we don't have anything to add
86             return $class->$orig(%opts)
87             if exists $opts{anon_package_prefix};
88             return $class->$orig(%opts)
89             unless @$superclasses && @$superclasses == 1;
90              
91             # XXX ::class_of?
92             my $sc = $superclasses->[0]->meta;
93              
94             #my $prefix
95             $opts{anon_package_prefix}
96             = $sc->is_anon
97             ? $sc->_anon_package_prefix
98             : $superclasses->[0] . $class->_anon_package_middle
99             ;
100              
101             # basically: if we have no superclasses, live with the default prefix; if
102             # we have a superclass and it's anon, use it's anon prefix; if we have a
103             # superclass and it's not anon, make a new prefix out of it
104             #
105             # cases where we have 2+ superclasses aren't handled right now; we use the
106             # Moose::Meta::Class::_anon_package_prefix() for those
107             #
108             # if we're passed in 'anon_package_prefix', then just use that.
109              
110             return $class->$orig(%opts);
111             };
112              
113             !!42;
114              
115             __END__
116              
117             =pod
118              
119             =encoding UTF-8
120              
121             =for :stopwords Chris Weyl
122              
123             =for :stopwords Wishlist flattr flattr'ed gittip gittip'ed
124              
125             =head1 NAME
126              
127             MooseX::TraitFor::Meta::Class::BetterAnonClassNames - Metaclass trait to *attempt* to demystify generated anonymous class names
128              
129             =head1 VERSION
130              
131             This document describes version 0.002002 of MooseX::TraitFor::Meta::Class::BetterAnonClassNames - released November 12, 2014 as part of MooseX-TraitFor-Meta-Class-BetterAnonClassNames.
132              
133             =head1 ATTRIBUTES
134              
135             =head2 is_anon
136              
137             Read-only, L<Boolean|Moose::Util::TypeConstraints/Default Type Constraints>,
138             default: false.
139              
140             Provides an attribute in the place of L<Class::MOP::Package/is_anon>.
141              
142             =head2 anon_package_prefix
143              
144             Read-only, L<String|Moose::Util::TypeConstraints/Default Type Constraints>
145              
146             =head1 METHODS
147              
148             =head2 _build_anon_package_prefix
149              
150             Builder method for the L</anon_package_prefix> attribute.
151              
152             =head2 _anon_package_middle
153              
154             Defines what the "middle" of our anonymous package names is; provided for ease
155             of overriding and hardcoded to:
156              
157             ::__ANON__::SERIAL::
158              
159             =head2 _anon_package_prefix
160              
161             Returns the full prefix used to generate anonymous package names; if called
162             on an instance then returns a sensible prefix (generally class name)
163             stashed in L</anon_package_prefix>; otherwise returns the result of a call
164             to L<Moose::Meta::Class/_anon_package_prefix>.
165              
166             =head2 create
167              
168             Set the package name to a nicer anonymous class name if is_anon is passed
169             and true and anon_package_prefix is passed and a non-empty string.
170              
171             =head2 create_anon_class
172              
173             Create an anonymous class, as via L<Moose::Meta::Class/create_anon_class>,
174             but with a kinder, gentler package name -- if possible.
175              
176             =head1 SUMMARY
177              
178             You really want to be looking at L<MooseX::Util/with_traits>.
179              
180             =head1 SEE ALSO
181              
182             Please see those modules/websites for more information related to this module.
183              
184             =over 4
185              
186             =item *
187              
188             L<MooseX::Util>
189              
190             =back
191              
192             =head1 SOURCE
193              
194             The development version is on github at L<http://https://github.com/RsrchBoy/moosex-traitfor-meta-class-betteranonclassnames>
195             and may be cloned from L<git://https://github.com/RsrchBoy/moosex-traitfor-meta-class-betteranonclassnames.git>
196              
197             =head1 BUGS
198              
199             Please report any bugs or feature requests on the bugtracker website
200             https://github.com/RsrchBoy/moosex-traitfor-meta-class-betteranonclassnames
201             /issues
202              
203             When submitting a bug or request, please include a test-file or a
204             patch to an existing test-file that illustrates the bug or desired
205             feature.
206              
207             =head1 AUTHOR
208              
209             Chris Weyl <cweyl@alumni.drew.edu>
210              
211             =head2 I'm a material boy in a material world
212              
213             =begin html
214              
215             <a href="https://www.gittip.com/RsrchBoy/"><img src="https://raw.githubusercontent.com/gittip/www.gittip.com/master/www/assets/%25version/logo.png" /></a>
216             <a href="http://bit.ly/rsrchboys-wishlist"><img src="http://wps.io/wp-content/uploads/2014/05/amazon_wishlist.resized.png" /></a>
217             <a href="https://flattr.com/submit/auto?user_id=RsrchBoy&url=https%3A%2F%2Fgithub.com%2FRsrchBoy%2Fmoosex-traitfor-meta-class-betteranonclassnames&title=RsrchBoy's%20CPAN%20MooseX-TraitFor-Meta-Class-BetterAnonClassNames&tags=%22RsrchBoy's%20MooseX-TraitFor-Meta-Class-BetterAnonClassNames%20in%20the%20CPAN%22"><img src="http://api.flattr.com/button/flattr-badge-large.png" /></a>
218              
219             =end html
220              
221             Please note B<I do not expect to be gittip'ed or flattr'ed for this work>,
222             rather B<it is simply a very pleasant surprise>. I largely create and release
223             works like this because I need them or I find it enjoyable; however, don't let
224             that stop you if you feel like it ;)
225              
226             L<Flattr this|https://flattr.com/submit/auto?user_id=RsrchBoy&url=https%3A%2F%2Fgithub.com%2FRsrchBoy%2Fmoosex-traitfor-meta-class-betteranonclassnames&title=RsrchBoy's%20CPAN%20MooseX-TraitFor-Meta-Class-BetterAnonClassNames&tags=%22RsrchBoy's%20MooseX-TraitFor-Meta-Class-BetterAnonClassNames%20in%20the%20CPAN%22>,
227             L<gittip me|https://www.gittip.com/RsrchBoy/>, or indulge my
228             L<Amazon Wishlist|http://bit.ly/rsrchboys-wishlist>... If you so desire.
229              
230             =head1 COPYRIGHT AND LICENSE
231              
232             This software is Copyright (c) 2014 by Chris Weyl.
233              
234             This is free software, licensed under:
235              
236             The GNU Lesser General Public License, Version 2.1, February 1999
237              
238             =cut