| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Tie::OneOff; |
|
2
|
|
|
|
|
|
|
our $VERSION = 1.03; |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=head1 NAME |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
Tie::OneOff - create tied variables without defining a separate package |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
require Tie::OneOff; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
tie my %REV, 'Tie::OneOff' => sub { |
|
13
|
|
|
|
|
|
|
reverse shift; |
|
14
|
|
|
|
|
|
|
}; |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
print "$REV{olleH}\n"; # Hello |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub make_counter { |
|
19
|
|
|
|
|
|
|
my $step = shift; |
|
20
|
|
|
|
|
|
|
my $i = 0; |
|
21
|
|
|
|
|
|
|
Tie::OneOff->scalar({ |
|
22
|
|
|
|
|
|
|
BASE => \$i, # Implies: STORE => sub { $i = shift } |
|
23
|
|
|
|
|
|
|
FETCH => sub { $i += $step }, |
|
24
|
|
|
|
|
|
|
}); |
|
25
|
|
|
|
|
|
|
} |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $c1 = make_counter(1); |
|
28
|
|
|
|
|
|
|
my $c2 = make_counter(2); |
|
29
|
|
|
|
|
|
|
$$c2 = 10; |
|
30
|
|
|
|
|
|
|
print "$$c1 $$c2 $$c2 $$c2 $$c1 $$c1\n"; # 1 12 14 16 2 3 |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub foo : lvalue { |
|
33
|
|
|
|
|
|
|
+Tie::OneOff->lvalue({ |
|
34
|
|
|
|
|
|
|
STORE => sub { print "foo()=$_[0]\n" }, |
|
35
|
|
|
|
|
|
|
FETCH => sub { "wibble" }, |
|
36
|
|
|
|
|
|
|
}); |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
foo='wobble'; # foo()=wobble |
|
40
|
|
|
|
|
|
|
print "foo()=", foo, "\n"; # foo()=wibble |
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
The Perl tie mechanism ties a Perl variable to a Perl object. This |
|
45
|
|
|
|
|
|
|
means that, conventionally, for each distinct set of tied variable |
|
46
|
|
|
|
|
|
|
semantics one needs to create a new package. The package symbol table |
|
47
|
|
|
|
|
|
|
then acts as a dispatch table for the intrinsic actions (such as |
|
48
|
|
|
|
|
|
|
C, C, C) that can be performed on Perl |
|
49
|
|
|
|
|
|
|
variables. |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Sometimes it would seem more natural to associate a dispatch table |
|
52
|
|
|
|
|
|
|
hash directly with the variable and pretend as if the intermediate |
|
53
|
|
|
|
|
|
|
object did not exist. This is what C does. |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
It is important to note that in this model there is no object to hold |
|
56
|
|
|
|
|
|
|
the instance data for the tied variable. The callbacks in the |
|
57
|
|
|
|
|
|
|
dispatch table are called not as object methods but as simple |
|
58
|
|
|
|
|
|
|
subroutines. If there is to be any instance information for a |
|
59
|
|
|
|
|
|
|
variable tied using C it must be in lexical variables |
|
60
|
|
|
|
|
|
|
that are referenced by the callback closures. |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
C does not itself provide any default callbacks. This |
|
63
|
|
|
|
|
|
|
can make defining a full featured hash interface rather tedious. To |
|
64
|
|
|
|
|
|
|
simplify matters the element C in the dispatch table can be used |
|
65
|
|
|
|
|
|
|
to specify a "base object" whose methods provide the default |
|
66
|
|
|
|
|
|
|
callbacks. If a reference to an unblessed Perl variable is specified |
|
67
|
|
|
|
|
|
|
as the C then the variable is blessed into the appropriate |
|
68
|
|
|
|
|
|
|
C package. In this case the unblessed variable used as |
|
69
|
|
|
|
|
|
|
the base must, of course, be of the same type as the variable that is |
|
70
|
|
|
|
|
|
|
being tied. |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
In C in the synopsis above, the variable C<$i> gets blessed |
|
73
|
|
|
|
|
|
|
into C. Since there is no explict STORE in the dispatch |
|
74
|
|
|
|
|
|
|
table, an attempt to store into a counter is implemented by calling |
|
75
|
|
|
|
|
|
|
C<(\$i)-ESTORE(@_)> which in turn is resolved as |
|
76
|
|
|
|
|
|
|
C which in turn is equivalent to C<$i=shift>. |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
Since many tied variables need only a C method C |
|
79
|
|
|
|
|
|
|
ties can also be specified by giving a simple code reference that is |
|
80
|
|
|
|
|
|
|
taken to be the variable's C callback. |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
For convience the class methods C, C and C take |
|
83
|
|
|
|
|
|
|
the same arguments as the tie inferface and return a reference to an |
|
84
|
|
|
|
|
|
|
anonymous tied variable. The class method C is like C |
|
85
|
|
|
|
|
|
|
but returns an lvalue rather than a reference. |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=head1 Relationship to other modules |
|
88
|
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
This module's original working title was Tie::Simple however it was |
|
90
|
|
|
|
|
|
|
eventually released as Tie::OneOff. Some time later another, |
|
91
|
|
|
|
|
|
|
substancially identical, module was developed independantly and |
|
92
|
|
|
|
|
|
|
released as L. |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
This module can be used as a trick to make functions that interpolate |
|
95
|
|
|
|
|
|
|
into strings but if that's all you want you may want to use |
|
96
|
|
|
|
|
|
|
L instead. |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
XXX Want XXX |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
L, L, L, L, L, L. |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=cut |
|
105
|
|
|
|
|
|
|
|
|
106
|
1
|
|
|
1
|
|
760
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
40
|
|
|
107
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
37
|
|
|
108
|
1
|
|
|
1
|
|
5
|
use base 'Exporter'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
648
|
|
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
my %not_pass_to_base = |
|
111
|
|
|
|
|
|
|
( |
|
112
|
|
|
|
|
|
|
DESTROY => 1, |
|
113
|
|
|
|
|
|
|
UNTIE => 1, |
|
114
|
|
|
|
|
|
|
); |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub AUTOLOAD { |
|
117
|
20
|
|
|
20
|
|
154
|
my $self = shift; |
|
118
|
20
|
50
|
|
|
|
138
|
my ($func) = our $AUTOLOAD =~ /(\w+)$/ or die; |
|
119
|
|
|
|
|
|
|
# All class methods are the contstuctor |
|
120
|
20
|
100
|
|
|
|
50
|
unless ( ref $self ) { |
|
121
|
7
|
50
|
|
|
|
29
|
unless ($func =~ /^TIE/) { |
|
122
|
0
|
|
|
|
|
0
|
require Carp; |
|
123
|
0
|
|
|
|
|
0
|
Carp::croak("Non-TIE class method $func called for $self"); |
|
124
|
|
|
|
|
|
|
} |
|
125
|
7
|
50
|
|
|
|
33
|
$self = bless ref $_[0] eq 'CODE' ? { FETCH => $_[0] } : |
|
|
|
100
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
ref $_[0] ? shift : { @_ }, $self; |
|
127
|
7
|
100
|
|
|
|
29
|
if ( my $base = $self->{BASE} ) { |
|
128
|
3
|
|
|
|
|
17
|
require Scalar::Util; |
|
129
|
3
|
50
|
|
|
|
12
|
unless ( Scalar::Util::blessed($base)) { |
|
130
|
3
|
|
|
|
|
7
|
my $type = ref $base; |
|
131
|
3
|
50
|
|
|
|
10
|
unless ( "TIE$type" eq $func ) { |
|
132
|
0
|
|
|
|
|
0
|
require Carp; |
|
133
|
0
|
|
0
|
|
|
0
|
$type ||= 'non-reference'; |
|
134
|
0
|
|
|
|
|
0
|
Carp::croak("BASE cannot be $type in " . __PACKAGE__ . "::$func"); |
|
135
|
|
|
|
|
|
|
} |
|
136
|
3
|
|
|
|
|
2060
|
require "Tie/\u\L$type.pm"; |
|
137
|
3
|
|
|
|
|
1896
|
bless $base, "Tie::Std\u\L$type"; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
} |
|
140
|
7
|
|
|
|
|
28
|
return $self; |
|
141
|
|
|
|
|
|
|
} |
|
142
|
13
|
100
|
|
|
|
37
|
my $code = $self->{$func} or do { |
|
143
|
2
|
50
|
|
|
|
7
|
return if $not_pass_to_base{$func}; |
|
144
|
2
|
|
|
|
|
3
|
my $base = $self->{BASE}; |
|
145
|
2
|
50
|
|
|
|
20
|
return $base->$func(@_) if $base; |
|
146
|
0
|
|
|
|
|
0
|
require Carp; |
|
147
|
0
|
|
|
|
|
0
|
Carp::croak("No $func handler defined in " . __PACKAGE__ . " object"); |
|
148
|
|
|
|
|
|
|
}; |
|
149
|
11
|
|
|
|
|
36
|
goto &$code; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub scalar { |
|
153
|
1
|
|
|
1
|
0
|
20
|
my $class = shift; |
|
154
|
1
|
|
|
|
|
6
|
tie my ($v), $class, @_; |
|
155
|
1
|
|
|
|
|
5
|
\$v; |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
sub lvalue : lvalue { |
|
159
|
2
|
|
|
2
|
0
|
79
|
my $class = shift; |
|
160
|
2
|
|
|
|
|
9
|
tie my($v), $class, @_; |
|
161
|
2
|
|
|
|
|
17
|
$v; |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub hash { |
|
165
|
1
|
|
|
1
|
0
|
19
|
my $class = shift; |
|
166
|
1
|
|
|
|
|
6
|
tie my(%v), $class, @_; |
|
167
|
1
|
|
|
|
|
4
|
\%v; |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
sub array { |
|
171
|
1
|
|
|
1
|
0
|
19
|
my $class = shift; |
|
172
|
1
|
|
|
|
|
8
|
tie my(@v), $class, @_; |
|
173
|
1
|
|
|
|
|
4
|
\@v; |
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
1; |