File Coverage

lib/Aspect/Library/Singleton.pm
Criterion Covered Total %
statement 23 23 100.0
branch 2 2 100.0
condition 1 3 33.3
subroutine 7 7 100.0
pod 0 1 0.0
total 33 36 91.6


line stmt bran cond sub pod time code
1             package Aspect::Library::Singleton;
2              
3 1     1   1987 use strict;
  1         3  
  1         54  
4 1     1   7 use warnings;
  1         2  
  1         34  
5 1     1   6 use Carp;
  1         1  
  1         77  
6 1     1   8 use Aspect;
  1         3  
  1         103  
7              
8 1     1   7 use base 'Aspect::Modular';
  1         3  
  1         555  
9              
10             my %Cache;
11              
12             sub get_advice {
13 1     1 0 2 my ($self, $constructor_matcher) = @_;
14             return before {
15 2     2   4 my $context = shift;
16 2         6 my $class = $context->self;
17 2   33     11 $class = ref $class || $class;
18              
19 2 100       6 if (exists $Cache{$class})
20 1         3 { $context->return_value($Cache{$class}) }
21             else
22 1         5 { $Cache{$class} = $context->run_original }
23              
24 1         8 } call $constructor_matcher;
25             }
26              
27             1;
28              
29             =head1 NAME
30              
31             Aspect::Library::Singleton - A singleton aspect
32              
33             =head1 SYNOPSIS
34              
35             use Aspect::Singleton;
36              
37             aspect Singleton => 'Foo::new';
38              
39             my $f1 = Foo->new;
40             my $f2 = Foo->new;
41              
42             # now $f1 and $f2 refer to the same object
43              
44             =head1 SUPER
45              
46             L
47              
48             =head1 DESCRIPTION
49              
50             A reusable aspect that forces singleton behavior on a constructor. The
51             constructor is defined by a pointcut spec: a string. regexp, or code ref.
52              
53             It is slightly different from C
54             (L):
55              
56             =over
57              
58             =item *
59              
60             No specific name requirement on the constructor for the external
61             interface, or for the implementation (C requires
62             clients use C, and that subclasses override
63             C<_new_instance()>). With aspects, you can change the cardinality of
64             your objects without changing the clients, or the objects themselves.
65              
66             =item *
67              
68             No need to inherit from anything- use pointcuts to specify the
69             constructors you want to memoize. Instead of I singleton
70             behavior from a base class, you are I it in, using the aspect.
71              
72             =item *
73              
74             No package variable or method is added to the callers namespace
75              
76             =back
77              
78             Note that this is just a special case of memoizing.
79              
80             =head1 SEE ALSO
81              
82             See the L pods for a guide to the Aspect module.
83              
84             You can find an example comparing the OO and AOP solutions in the
85             C directory of the distribution.
86              
87             =cut
88