File Coverage

blib/lib/Class/FakeAttributes.pm
Criterion Covered Total %
statement 12 25 48.0
branch n/a
condition n/a
subroutine 4 9 44.4
pod 4 4 100.0
total 20 38 52.6


line stmt bran cond sub pod time code
1             package Class::FakeAttributes;
2             our $VERSION = 0.01;
3              
4             =head1 NAME
5              
6             Class::FakeAttributes - Provide fake attributes for non-hash-based objects
7              
8             =head1 SYNOPSIS
9              
10             use base qw;
11            
12             sub something
13             {
14             my ($self, $whatever) = @_;
15              
16             $self->set_attribute(motto => $whatever);
17             my $size = $self->get_attribute('size');
18             # etc
19              
20             =head1 WARNING
21              
22             This is version 0.01. It exists for discussion. Do not rely on it.
23             Everything is subject to change, including the module's functionality, API,
24             name, and even its existence. Comments are welcome on the
25             S mailing list.
26              
27             =head1 DESCRIPTION
28              
29             Most Perl classes use hash-based objects, and subclasses can easily add more
30             attributes (instance data) with new hash keys. But some classes are not based
31             on hashes. A subclass of such a class can use C to add
32             attributes (or at least to emulate doing so).
33              
34             C is a mixin class: the only sensible use is to inherit
35             from it, and it only makes sense to do that when also inheriting from something
36             else as well.
37              
38             =cut
39              
40 1     1   24965 use strict;
  1         3  
  1         44  
41 1     1   6 use warnings;
  1         2  
  1         34  
42              
43 1     1   1060 use NEXT;
  1         6073  
  1         218  
44              
45              
46             # global hash for all attributes of all objects that use this (regardless of
47             # their class), keyed by the stringification of objects' blessed references:
48             our %attribute;
49              
50             =head1 METHODS
51              
52             =head2 C
53              
54             Use C to set an attribute on an object. Where with a
55             hash-based object you would have written:
56              
57             $self->{key} = $value;
58              
59             instead write:
60              
61             $self->set_attribute(key => $value);
62              
63             =cut
64              
65             sub set_attribute
66             {
67 0     0 1   my ($self, $key, $val) = @_;
68              
69 0           $attribute{$self}{$key} = $val;
70              
71             }
72              
73             =head2 C
74              
75             Get the value of an attribute (set by C) with
76             C. Instead of this hash-based code:
77              
78             my $value = $self->{key};
79              
80             do:
81              
82             my $value = $self->get_attribute('key');
83              
84             =cut
85              
86             sub get_attribute
87             {
88 0     0 1   my ($self, $key) = @_;
89              
90 0           $attribute{$self}{$key};
91             }
92              
93             =head2 C
94              
95             For an attribute that has a list of values, append to that list with
96             C. Instead of this hash-based code:
97              
98             push @{$self->{key}}, $value;
99              
100             do:
101              
102             $self->push_attribute(key => $value);
103              
104             Multiple values can be pushed at once:
105              
106             $self->push_attribute(food => @fruit);
107              
108             =cut
109              
110             sub push_attribute
111             {
112 0     0 1   my ($self, $key, @val) = @_;
113              
114 0           push @{$attribute{$self}{$key}}, @val;
  0            
115              
116             }
117              
118             =head2 C
119              
120             Retrieve the list of all values for a key with C. Instead of
121             this hash-based code:
122              
123             foreach (@{$self->{key})
124              
125             do:
126              
127             foreach ($self->attribute_list('key'))
128              
129             =cut
130              
131             sub attribute_list
132             {
133 0     0 1   my ($self, $key) = @_;
134              
135             # If $self doesn't have any attributes then don't complain, just return an
136             # empty list (same as if it has some attributes but just not any with key
137             # $key):
138 1     1   12 no warnings 'uninitialized';
  1         2  
  1         151  
139 0           @{$attribute{$self}{$key}};
  0            
140             }
141              
142             =head1 MEMORY LEAKAGE
143              
144             The memory used to store an object's attributes is freed in a C method
145             provided by C. If C doesn't get called then
146             memory will be leaked. The best way to ensure memory gets freed up properly is
147             to put C at the start of the inheritance list. That is,
148             don't do this:
149              
150             use base qw;
151              
152             do this:
153              
154             use base qw;
155              
156             C uses L module|NEXT> to ensure that, so
157             long as it is listed first, any C method in other superclasses will
158             also be invoked.
159              
160             =cut
161              
162             sub DESTROY
163             {
164 0     0     my ($self) = @_;
165              
166             # Free up the memory used for the attributes of this object:
167 0           delete $attribute{$self};
168              
169             # Invoke any other DESTROY() method that would've been called had this class
170             # not existed:
171 0           $self->NEXT::DISTINCT::DESTROY;
172              
173             }
174              
175              
176             1;
177              
178             =head1 AUTHOR
179              
180             Smylers
181              
182             =head1 COPYRIGHT
183              
184             E<169> Copyright Smylers 2003. All rights reserved. This module is software
185             libre. It may be used, redistributed, or modified under the terms of the
186             Artistic License (the unnumbered version that comes with Perl 5.6.1, among
187             others) or the GNU General Public License version 2.