File Coverage

blib/lib/MooseX/Singleton/Role/Meta/Method/Constructor.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             package MooseX::Singleton::Role::Meta::Method::Constructor;
2 7     7   21 use Moose::Role;
  7         8  
  7         31  
3              
4             our $VERSION = '0.30';
5              
6             if ( $Moose::VERSION < 1.9900 ) {
7             override _initialize_body => sub {
8             my $self = shift;
9              
10             # TODO:
11             # the %options should also include a both
12             # a call 'initializer' and call 'SUPER::'
13             # options, which should cover approx 90%
14             # of the possible use cases (even if it
15             # requires some adaption on the part of
16             # the author, after all, nothing is free)
17             my $source = 'sub {';
18             $source .= "\n" . 'my $class = shift;';
19              
20             $source .= "\n"
21             . 'my $existing = do { no strict "refs"; no warnings "once"; \${"$class\::singleton"}; };';
22             $source .= "\n" . 'return ${$existing} if ${$existing};';
23              
24             $source .= "\n" . 'return $class->Moose::Object::new(@_)';
25             $source
26             .= "\n"
27             . ' if $class ne \''
28             . $self->associated_metaclass->name . '\';';
29              
30             $source .= $self->_generate_params( '$params', '$class' );
31             $source .= $self->_generate_instance( '$instance', '$class' );
32             $source .= $self->_generate_slot_initializers;
33              
34             $source .= ";\n" . $self->_generate_triggers();
35             $source .= ";\n" . $self->_generate_BUILDALL();
36              
37             $source .= ";\n" . 'return ${$existing} = $instance';
38             $source .= ";\n" . '}';
39             warn $source if $self->options->{debug};
40              
41             my $attrs = $self->_attributes;
42              
43             my @type_constraints
44             = map { $_->can('type_constraint') ? $_->type_constraint : undef }
45             @$attrs;
46              
47             my @type_constraint_bodies
48             = map { defined $_ ? $_->_compiled_type_constraint : undef; }
49             @type_constraints;
50              
51             my $defaults = [map { $_->default } @$attrs];
52              
53             my ( $code, $e ) = $self->_compile_code(
54             code => $source,
55             environment => {
56             '$meta' => \$self,
57             '$attrs' => \$attrs,
58             '$defaults' => \$defaults,
59             '@type_constraints' => \@type_constraints,
60             '@type_constraint_bodies' => \@type_constraint_bodies,
61             },
62             );
63              
64             $self->throw_error(
65             "Could not eval the constructor :\n\n$source\n\nbecause :\n\n$e",
66             error => $e, data => $source )
67             if $e;
68              
69             $self->{'body'} = $code;
70             };
71             }
72              
73             # Ideally we'd be setting this in the constructor, but the new() methods in
74             # what the parent classes are not well-factored.
75             #
76             # This is all a nasty hack, though. We need to fix Class::MOP::Inlined to
77             # allow constructor class roles to say "if the parent class has role X,
78             # inline".
79             override _expected_method_class => sub {
80             my $self = shift;
81              
82             my $super_value = super();
83             if ( $super_value eq 'Moose::Object' ) {
84             for my $parent ( map { Class::MOP::class_of($_) }
85             $self->associated_metaclass->superclasses ) {
86             return $parent->name
87             if $parent->is_anon_class
88             && grep { $_->name eq 'Moose::Object' }
89             map { Class::MOP::class_of($_) } $parent->superclasses;
90             }
91             }
92              
93             return $super_value;
94             };
95              
96 7     7   24513 no Moose::Role;
  7         10  
  7         24  
97              
98             1;
99              
100             # ABSTRACT: Constructor method role for MooseX::Singleton
101              
102             __END__
103              
104             =pod
105              
106             =encoding UTF-8
107              
108             =head1 NAME
109              
110             MooseX::Singleton::Role::Meta::Method::Constructor - Constructor method role for MooseX::Singleton
111              
112             =head1 VERSION
113              
114             version 0.30
115              
116             =head1 DESCRIPTION
117              
118             This role overrides the generated object C<new> method so that it returns the
119             singleton if it already exists.
120              
121             =head1 SUPPORT
122              
123             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-Singleton>
124             (or L<bug-MooseX-Singleton@rt.cpan.org|mailto:bug-MooseX-Singleton@rt.cpan.org>).
125              
126             There is also a mailing list available for users of this distribution, at
127             L<http://lists.perl.org/list/moose.html>.
128              
129             There is also an irc channel available for users of this distribution, at
130             L<C<#moose> on C<irc.perl.org>|irc://irc.perl.org/#moose>.
131              
132             =head1 AUTHOR
133              
134             Shawn M Moore <code@sartak.org>
135              
136             =head1 COPYRIGHT AND LICENSE
137              
138             This software is copyright (c) 2007 by Shawn M Moore.
139              
140             This is free software; you can redistribute it and/or modify it under
141             the same terms as the Perl 5 programming language system itself.
142              
143             =cut