line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Simple::Accessor; |
2
|
|
|
|
|
|
|
$Simple::Accessor::VERSION = '1.11'; |
3
|
1
|
|
|
1
|
|
695
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
22
|
|
4
|
1
|
|
|
1
|
|
3
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
94
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# ABSTRACT: a light and simple way to provide accessor in perl |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
Simple::Accessor - very simple, light and powerful accessor |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 VERSION |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
version 1.11 |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 DESCRIPTION |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Simple::Accessor provides a simple object layer without any dependency. |
18
|
|
|
|
|
|
|
It can be used where other ORM could be considered too heavy. |
19
|
|
|
|
|
|
|
But it has also the main advantage to only need one single line of code. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
It can be easily used in scripts... |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 Usage |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Create a package and just call Simple::Accessor. |
26
|
|
|
|
|
|
|
The new method will be imported for you, and all accessors will be directly |
27
|
|
|
|
|
|
|
accessible. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
package MyClass; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# that s all what you need ! no more line required |
32
|
|
|
|
|
|
|
use Simple::Accessor qw{foo bar cherry apple}; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
You can now call 'new' on your class, and create objects using these attributes |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
package main; |
37
|
|
|
|
|
|
|
use MyClass; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $o = MyClass->new() |
40
|
|
|
|
|
|
|
or MyClass->new(bar => 42) |
41
|
|
|
|
|
|
|
or MyClass->new(apple => 'fruit', cherry => 'fruit', banana => 'yummy'); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
You can get / set any value using the accessor |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
is $o->bar(), 42; |
46
|
|
|
|
|
|
|
$o->bar(51); |
47
|
|
|
|
|
|
|
is $o->bar(), 51; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
You can provide your own init method that will be call by new with default args. |
50
|
|
|
|
|
|
|
This is optional. |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
package MyClass; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub build { # previously known as initialize |
55
|
|
|
|
|
|
|
my ($self, %opts) = @_; |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
$self->foo(12345); |
58
|
|
|
|
|
|
|
} |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
You can also control the object after or before its creation using |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub _before_build { |
63
|
|
|
|
|
|
|
my ($self, %opts) = @_; |
64
|
|
|
|
|
|
|
... |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub _after_build { |
68
|
|
|
|
|
|
|
my ($self, %opts) = @_; |
69
|
|
|
|
|
|
|
... |
70
|
|
|
|
|
|
|
bless $self, 'Basket'; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
You can also provide individual builders / initializers |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
sub _build_bar { # previously known as _initialize_bar |
76
|
|
|
|
|
|
|
# will be used if no value has been provided for bar |
77
|
|
|
|
|
|
|
1031; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub _build_cherry { |
81
|
|
|
|
|
|
|
'red'; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
You can even use a very basic but useful hook system. |
85
|
|
|
|
|
|
|
Any false value return by before or validate, will stop the setting process. |
86
|
|
|
|
|
|
|
Be careful with the after method, as there is no protection against infinite loop. |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub _before_foo { |
89
|
|
|
|
|
|
|
my ($self, $v) = @_; |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# do whatever you want with $v |
92
|
|
|
|
|
|
|
return 1 or 0; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _validate_foo { |
96
|
|
|
|
|
|
|
my ($self, $v) = @_; |
97
|
|
|
|
|
|
|
# invalid value ( will not be set ) |
98
|
|
|
|
|
|
|
return 0 if ( $v == 42); |
99
|
|
|
|
|
|
|
# valid value |
100
|
|
|
|
|
|
|
return 1; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub _after_cherry { |
104
|
|
|
|
|
|
|
my ($self) = @_; |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# use the set value for extra operations |
107
|
|
|
|
|
|
|
$self->apple($self->cherry()); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head1 METHODS |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
None. The only public method provided is the classical import. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=cut |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub import { |
117
|
3
|
|
|
3
|
|
1109
|
my ( $class, @attr ) = @_; |
118
|
|
|
|
|
|
|
|
119
|
3
|
|
|
|
|
5
|
my $from = caller(); |
120
|
|
|
|
|
|
|
|
121
|
3
|
|
|
|
|
3
|
_add_new($from); |
122
|
3
|
|
|
|
|
5
|
_add_accessors( to => $from, attributes => \@attr ); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub _add_new { |
126
|
3
|
|
|
3
|
|
3
|
my $class = shift; |
127
|
3
|
50
|
|
|
|
6
|
return unless $class; |
128
|
|
|
|
|
|
|
|
129
|
3
|
|
|
|
|
5
|
my $new = $class . '::new'; |
130
|
|
|
|
|
|
|
{ |
131
|
1
|
|
|
1
|
|
3
|
no strict 'refs'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
182
|
|
|
3
|
|
|
|
|
3
|
|
132
|
|
|
|
|
|
|
*$new = sub { |
133
|
8
|
|
|
8
|
|
954
|
my ( $class, %opts ) = @_; |
134
|
|
|
|
|
|
|
|
135
|
8
|
|
|
|
|
13
|
my $self = bless {}, $class; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# set values if attributes exist |
138
|
|
|
|
|
|
|
map { |
139
|
8
|
|
|
|
|
13
|
eval { $self->$_( $opts{$_} ) } |
|
3
|
|
|
|
|
11
|
|
|
3
|
|
|
|
|
15
|
|
140
|
|
|
|
|
|
|
} keys %opts; |
141
|
|
|
|
|
|
|
|
142
|
8
|
50
|
|
|
|
34
|
if ( $self->can( '_before_build') ) { |
143
|
0
|
|
|
|
|
0
|
$self->_before_build( %opts ); |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
8
|
|
|
|
|
9
|
foreach my $init ( 'build', 'initialize' ) { |
147
|
16
|
100
|
|
|
|
36
|
if ( $self->can( $init ) ) { |
148
|
4
|
50
|
|
|
|
47
|
return unless $self->$init(%opts); |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
8
|
50
|
|
|
|
36
|
if ( $self->can( '_after_build') ) { |
153
|
0
|
|
|
|
|
0
|
$self->_after_build( %opts ); |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
8
|
|
|
|
|
13
|
return $self; |
157
|
3
|
|
|
|
|
19
|
}; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
sub _add_accessors { |
162
|
3
|
|
|
3
|
|
6
|
my (%opts) = @_; |
163
|
|
|
|
|
|
|
|
164
|
3
|
50
|
|
|
|
5
|
return unless $opts{to}; |
165
|
3
|
|
|
|
|
3
|
my @attributes = @{ $opts{attributes} }; |
|
3
|
|
|
|
|
5
|
|
166
|
3
|
50
|
|
|
|
7
|
return unless @attributes; |
167
|
|
|
|
|
|
|
|
168
|
3
|
|
|
|
|
4
|
foreach my $att (@attributes) { |
169
|
10
|
|
|
|
|
10
|
my $accessor = $opts{to} . "::$att"; |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# allow symbolic refs to typeglob |
172
|
1
|
|
|
1
|
|
3
|
no strict 'refs'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
153
|
|
173
|
|
|
|
|
|
|
*$accessor = sub { |
174
|
34
|
|
|
34
|
|
1244
|
my ( $self, $v ) = @_; |
175
|
34
|
100
|
|
|
|
73
|
if ( defined $v ) { |
|
|
100
|
|
|
|
|
|
176
|
15
|
|
|
|
|
20
|
foreach (qw{before validate set after}) { |
177
|
58
|
100
|
|
|
|
73
|
if ( $_ eq 'set' ) { |
178
|
14
|
|
|
|
|
20
|
$self->{$att} = $v; |
179
|
14
|
|
|
|
|
14
|
next; |
180
|
|
|
|
|
|
|
} |
181
|
44
|
|
|
|
|
48
|
my $sub = '_' . $_ . '_' . $att; |
182
|
44
|
100
|
|
|
|
167
|
if ( $self->can( $sub ) ) { |
183
|
4
|
100
|
|
|
|
9
|
return unless $self->$sub($v); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
elsif ( !defined $self->{$att} ) { |
188
|
|
|
|
|
|
|
# try to initialize the value (try first with build) |
189
|
|
|
|
|
|
|
# initialize is here for backward compatibility with older versions |
190
|
7
|
|
|
|
|
7
|
foreach my $builder ( qw{build initialize} ) { |
191
|
14
|
|
|
|
|
18
|
my $sub = '_' . $builder . '_' . $att; |
192
|
14
|
100
|
|
|
|
51
|
if ( $self->can( $sub ) ) { |
193
|
1
|
|
|
|
|
3
|
return $self->{$att} = $self->$sub(); |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
|
198
|
32
|
|
|
|
|
77
|
return $self->{$att}; |
199
|
10
|
|
|
|
|
39
|
}; |
200
|
|
|
|
|
|
|
} |
201
|
3
|
|
|
|
|
187
|
@attributes = (); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
1; |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=head1 CONTRIBUTE |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
You can contribute to this project on github https://github.com/atoomic/Simple-Accessor |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
=cut |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
__END__ |