|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Class::MethodVars;  | 
| 
2
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
1145
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
    | 
| 
3
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
8
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
    | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
14204
 | 
 use NEXT;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3785
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1895
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '1.'.qw $Rev: 133 $[1];  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our %Configs; # Needs to be accessible to Class::Framework  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %OptionsMap = (  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'^args'=>'hatargs',  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'hatargs'=>'hatargs',  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'varargs'=>'varargs',  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'^fields'=>'hatfields',  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'hatfields'=>'hatfields',  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'varfields'=>'varfields',  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'^this'=>'hatthis',  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'hatthis'=>'hatthis',  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'varthis'=>'varthis',  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'subthis'=>'subthis',  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'^class'=>'hatclass',  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'hatclass'=>'hatclass',  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'varclass'=>'varclass',  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'subclass'=>'subclass',  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	'debug'=>'debug',  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %DefaultOptions = (  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	hatargs=>1,  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	hatfields=>1,  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	subthis=>1,  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	subclass=>1,  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# No varthis and varclass because that causes an implicit use vars which is bad for a default.  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub __DefaultConfigs() {  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	return {  | 
| 
38
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
16
 | 
 		fieldhatprefix=>"",  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		fieldvarprefix=>"",  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		class=>"__CLASS__",  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		this=>"this",  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		fields=>[],  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		rwfields=>[],  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		rofields=>[],  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		wofields=>[],  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		hiddenfields=>[],  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		options=>{ %DefaultOptions }  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	};  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub import {  | 
| 
52
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
1
 | 
 	shift; # You should NEVER be @ISA = "Class::MethodVars"  | 
| 
53
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	my $package = caller;  | 
| 
54
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	if ($Configs{$package}) {  | 
| 
55
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		require Carp;  | 
| 
56
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		Carp::croak "Double import into this package!";  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
58
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
7
 | 
 	my $Config = $Configs{$package}||=__DefaultConfigs;  | 
| 
59
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	my $cpos = 0;  | 
| 
60
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	while (@_) {  | 
| 
61
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $cmd = shift;  | 
| 
62
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$cpos++;  | 
| 
63
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 		if ($cpos == 1 and ref($cmd)) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			push(@{$Config->{rwfields}},@$cmd);  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd eq '-this') {  | 
| 
66
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$Config->{this} = shift;  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd eq '-class') {  | 
| 
68
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$Config->{class} = shift;  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cpos == 1 and not $cmd=~/^[\+-]/) {  | 
| 
70
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			push(@{$Config->{rwfields}},$cmd);  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
71
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 			while (@_ and not $_[0]=~/^-/) {  | 
| 
72
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				push(@{$Config->{rwfields}},shift);  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd eq '-fields' or $cmd eq '-field') {  | 
| 
75
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 			if (@_ and ref($_[0])) {  | 
| 
76
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				push(@{$Config->{rwfields}},@{shift()});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			} else {  | 
| 
78
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 				while (@_ and not $_[0]=~/^-/) {  | 
| 
79
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 					push(@{$Config->{rwfields}},shift);  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd =~ /^-(r[wo]|wo|hidden)fields?$/) {  | 
| 
83
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			my $fieldtype = lc $1."fields";  | 
| 
84
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 			if (@_ and ref($_[0])) {  | 
| 
85
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				push(@{$Config->{$fieldtype}},@{shift()});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			} else {  | 
| 
87
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 				while (@_ and not $_[0]=~/^-/) {  | 
| 
88
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 					push(@{$Config->{$fieldtype}},shift);  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 				}  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd eq '-fieldvarprefix') {  | 
| 
92
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$Config->{fieldvarprefix} = shift;  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd eq '-fieldhatprefix') {  | 
| 
94
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$Config->{fieldhatprefix} = shift;  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} elsif ($cmd=~/^([+-])(.*)$/ and $OptionsMap{$2}) {  | 
| 
96
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			my ($toggle,$option) = ($1,$2);  | 
| 
97
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 			if ($toggle eq '-' and @_ and $_[0]=~/^(?:[10]|ON|OFF|TRUE|FALSE)$/i) { # 'it's okay - you would have -fields if expecting field names...  | 
| 
 
 | 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
98
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 				$toggle = shift;  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 			}  | 
| 
100
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$toggle = grep { lc($toggle) eq lc($_) } qw( - 1 ON TRUE );  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
101
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$Config->{options}->{$option} = $toggle;  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
103
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			require Carp;  | 
| 
104
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			local $Carp::CarpLevel = 1;  | 
| 
105
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "I don't know what to do with \"$cmd\"";  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
108
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	$Config->{fields} = [ Class::MethodVars::_Private::unique(@{$Config->{rwfields}},@{$Config->{rofields}},@{$Config->{wofields}},@{$Config->{hiddenfields}}) ];  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#FIXME: I should probably whine if people use the same field name for a -rofield as a -wofield (for example).  | 
| 
110
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	my @bad_field_names = grep { not /\A\w+\z/ } @{$Config->{fields}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
111
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	if (@bad_field_names) {  | 
| 
112
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		require Carp;  | 
| 
113
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if (eval { require Lingua::EN::Inflect; 1 }) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
114
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak Lingua::EN::Inflect::inflect("Invalid field PL(name,".@bad_field_names."): ").join(", ",@bad_field_names);  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
116
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			local $" = ", ";  | 
| 
117
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Invalid field name(s): @bad_field_names";  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
120
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	$Config->{allfields} = [ Class::MethodVars::_Private::findBaseFields($package) ]; # This will pull in self and base fields.  | 
| 
121
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	$Config->{options}->{subthis} = 0 if $Config->{this}=~/^\$?_$/;  | 
| 
122
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 	$Config->{options}->{subclass} = 0 if $Config->{class}=~/^\$?_$/;  | 
| 
123
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
 	eval 'unshift @'.$package.'::ISA,q('.__PACKAGE__.'::_ATTRS)';  | 
| 
124
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
 	eval 'package '.$package.'; sub '.$Config->{this}.'();' if $Config->{options}->{subthis};  | 
| 
125
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
 	eval 'package '.$package.'; sub '.$Config->{class}.'();' if $Config->{options}->{subclass};  | 
| 
126
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	my @varnames;  | 
| 
127
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	push(@varnames,$Config->{this}) if $Config->{options}->{varthis};  | 
| 
128
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	push(@varnames,$Config->{class}) if $Config->{options}->{varclass};  | 
| 
129
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	push(@varnames,map { $Config->{fieldvarprefix}.$_ } @{$Config->{fields}}) if $Config->{options}->{varfields};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# Can't do varargs, because I don't know what the args will be in advance!  | 
| 
131
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	eval 'package '.$package.'; use vars qw('.join(" ",map { s{^(?![\%\$\@])}{\$}; $_ } @varnames).');' if @varnames;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
132
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
153
 | 
 	1;  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub Method {  | 
| 
136
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 	my ($package, $symbol, $referent, $attr, $data, $stage) = @_;  | 
| 
137
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
9
 | 
 	no warnings 'redefine';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
    | 
| 
138
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 	no strict 'refs';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1717
 | 
    | 
| 
139
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (0 and defined($symbol) and *{$symbol}{NAME} eq 'ANON') {  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#   ^--- DISABLED!  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# Darn, need to find a better symbol. (Probably :Method is not on the first prototype...)  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#XXX: This doesn't work. Even $referent points to the wrong thing :(  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#	Can't figure out true name, can't figure out true reference = can't put Humpty Dumpty back together again :(  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		($symbol) = eval 'grep { *{$_}{NAME} ne "ANON" } grep { *{$_}{CODE} and *{$_}{CODE} eq $referent } values %'.$package.'::';  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
146
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	if (not defined($symbol) or *{$symbol}{NAME} eq 'ANON') {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
147
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		require Carp;  | 
| 
148
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		local $Carp::CarpLevel = 3;  | 
| 
149
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if ($^S) {  | 
| 
150
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Unable to identify the name of subroutine at $referent. You appear to be calling this inside an eval. This is a known bug - please \"use\" this module at the start of your application.\n";  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
152
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Unable to identify the name of subroutine at $referent. Please ensure :Method is on the first prototype.\n";  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# Don't try and apply the magic to a closure, this attribute is not set up for it.  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
156
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my ($self,@args);  | 
| 
157
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	my $Config = $Configs{$package}||__DefaultConfigs;  | 
| 
158
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$data = "." unless defined $data;  | 
| 
159
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (ref $data) {  | 
| 
160
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		($self,@args) = @$data;  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
162
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		($self,@args) = split(/[,\s]+/,$data);  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
164
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self = $Config->{this} if $self eq '.';  | 
| 
165
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self=~s{^\$}{};  | 
| 
166
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($self eq "_") {  | 
| 
167
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self = "";  | 
| 
168
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'local $_ = (ref($_[0]) and UNIVERSAL::isa($_[0],q('.$package.')))?shift:$_; my $me = $_;' if $Config->{options}->{varthis};  | 
| 
169
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'my $me = shift;' unless $Config->{options}->{varthis};  | 
| 
170
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'local ${^__} = $me;' if $Config->{options}->{hatthis};  | 
| 
171
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'local $_ = (ref($_[0]) and UNIVERSAL::isa($_[0],q('.$package.')))?shift:$_; my $me = $_;' unless $self;  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
173
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $selfname = $self;  | 
| 
174
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self = 'my $me = shift;';  | 
| 
175
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.='local *'.$package.'::'.$selfname.' = sub { $me };' if $Config->{options}->{subthis};  | 
| 
176
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.='local ${^_'.$selfname.'} = $me;' if $Config->{options}->{hatthis};  | 
| 
177
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.='local *'.$package.'::'.$selfname.' = \$me;' if $Config->{options}->{varthis};  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#$self = 'my $me = $_[0]; local *'.$package.'::'.$self.' = sub { $me }; local ${^_'.$self.'} = $_[0]; local *'.$package.'::'.$self.' = \shift;'  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
180
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (0) { # This is all too late. Needed to do it in BEGIN if I was going to do it at all.  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		my @varargs = @args;  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		eval 'package '.$package.'; use vars qw('.join(" ",grep { $_ ne "_" } map { s{^(?![\%\$\@])}{\$}; $_ } @varargs).');' if @varargs;  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
184
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for (@args) {  | 
| 
185
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $aname = $_;  | 
| 
186
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 		if ($aname=~/^\@(\w+)$/ and $aname eq $args[-1]) {  | 
| 
187
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$aname = $1;  | 
| 
188
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_ = ''; # This alters @args!  | 
| 
189
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'local @{^_'.$aname.'} = @_;' if $Config->{options}->{hatargs};  | 
| 
190
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'my @args = @_; local *'.$package.'::'.$aname.' = \@args;' if $Config->{options}->{varargs};  | 
| 
191
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			next;  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
193
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 		if ($aname=~/^\%(\w+)$/ and $aname eq $args[-1]) {  | 
| 
194
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$aname = $1;  | 
| 
195
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_ = ''; # This alters @args!  | 
| 
196
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'local %{^_'.$aname.'} = @_;' if $Config->{options}->{hatargs};  | 
| 
197
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'my %args = @_; local *'.$package.'::'.$aname.' = \%args;' if $Config->{options}->{varargs};  | 
| 
198
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			next;  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
200
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$aname=~s{^\$}{}; # Allow, but ignore leading dollar sigal.  | 
| 
201
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		unless ($aname=~/^\w+$/) {  | 
| 
202
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			require Carp;  | 
| 
203
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			local $Carp::CarpLevel = 1;  | 
| 
204
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Bad argument name: $aname (@args)";  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
206
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_ = ''; # This alters @args!  | 
| 
207
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if ($aname eq '_') {  | 
| 
208
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.='local $_ = $_[0];';  | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
210
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.='local ${^_'.$aname.'} = $_[0];' if $Config->{options}->{hatargs};  | 
| 
211
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.='local *'.$package.'::'.$aname.' = \$_[0];' if $Config->{options}->{varargs};  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
213
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_.='shift;';  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
215
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my @fields = @{$Config->{allfields}};  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
216
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for (@fields) {  | 
| 
217
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $fname = $_;  | 
| 
218
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_ = "";  | 
| 
219
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_.='local *{^_'.$Config->{fieldhatprefix}.$fname.'} = \$me->{q('.$fname.')};' if $Config->{options}->{hatfields};  | 
| 
220
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_.='local *'.$package.'::'.$Config->{fieldvarprefix}.$fname.' = \$me->{q('.$fname.')};' if $Config->{options}->{varfields};  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
222
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $proto = prototype $referent;  | 
| 
223
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (defined $proto) {  | 
| 
224
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$proto = "($proto)";  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
226
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$proto = "";  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
228
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($Config->{options}->{debug}) {  | 
| 
229
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $subdecl = "sub ".$package."::".(*{$symbol}{NAME}).$proto." {\n\t$self\n\t@fields\n\t@args\n\t\$referent->(\@_)\n};\n";  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
230
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$subdecl=~s{;(?!\n)\s*}{;\n\t}gs;  | 
| 
231
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		warn $subdecl;  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
233
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	local $@;  | 
| 
234
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $subdecl = "package $package; sub $proto {  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		$self  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		@fields  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		@args  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		\$referent->(\@_)  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	};";  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#*{$symbol} = eval $subdecl;  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#die $@."\n$subdecl" if $@;  | 
| 
242
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $subref = eval $subdecl;  | 
| 
243
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	die "Failure to create sub: ".$@."\n$subdecl" if $@;  | 
| 
244
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my ($sympkg,$symname) = (*{$symbol}{PACKAGE},*{$symbol}{NAME});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	eval '*{$symbol} = $subref; 1' or warn "Assigning symbol: $@"; # I don't know why this doesn't work any more.  | 
| 
246
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	eval '$'.$sympkg.'::{$symname} = $subref' or die "Failed to assign symbol *{$symbol}{PACKAGE}::*{$symbol}{NAME}: $@";  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub ClassMethod {  | 
| 
250
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 	my ($package, $symbol, $referent, $attr, $data, $stage) = @_;  | 
| 
251
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
7
 | 
 	no warnings 'redefine';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
    | 
| 
252
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
13
 | 
 	no strict 'refs';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1755
 | 
    | 
| 
253
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (0 and defined($symbol) and *{$symbol}{NAME} eq 'ANON') {  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#   ^--- DISABLED!  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# Darn, need to find a better symbol. (Probably :Method is not on the first prototype...)  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#XXX: This doesn't work. Even $referent points to the wrong thing :(  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#	Can't figure out true name, can't figure out true reference = can't put Humpty Dumpty back together again :(  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		($symbol) = eval 'grep { *{$_}{NAME} ne "ANON" } grep { *{$_}{CODE} and *{$_}{CODE} eq $referent } values %'.$package.'::';  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
260
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	if (not defined($symbol) or *{$symbol}{NAME} eq 'ANON') {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
261
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		require Carp;  | 
| 
262
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		local $Carp::CarpLevel = 3;  | 
| 
263
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if ($^S) {  | 
| 
264
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Unable to identify the name of subroutine at $referent. You appear to be calling this inside an eval. This is a known bug - please \"use\" this module at the start of your application.\n";  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
266
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Unable to identify the name of subroutine at $referent. Please ensure :Method is on the first prototype.\n";  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		# Don't try and apply the magic to a closure, this attribute is not set up for it.  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
270
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my ($class,@args);  | 
| 
271
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	my $Config = $Configs{$package}||__DefaultConfigs;  | 
| 
272
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$data = "." unless defined $data;  | 
| 
273
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (ref $data) {  | 
| 
274
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		($class,@args) = @$data;  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
276
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		($class,@args) = split(/[,\s]+/,$data);  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
278
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$class = $Config->{class} if $class eq '.';  | 
| 
279
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $self = $Config->{this};  | 
| 
280
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$class=~s{^\$}{};  | 
| 
281
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self=~s{^\$}{};  | 
| 
282
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($self eq "_") {  | 
| 
283
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self = "";  | 
| 
284
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'local $_ = (ref($_[0]) and UNIVERSAL::isa($_[0],q('.$package.')))?shift:$_; my $me = $_;' if $Config->{options}->{varthis};  | 
| 
285
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'my $me = shift;' unless $Config->{options}->{varthis};  | 
| 
286
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'local ${^__} = $me;' if $Config->{options}->{hatthis};  | 
| 
287
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.= 'local $_ = (ref($_[0]) and UNIVERSAL::isa($_[0],q('.$package.')))?shift:$_; my $me = $_;' unless $self;  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
289
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $selfname = $self;  | 
| 
290
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self = 'my $me = shift;';  | 
| 
291
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.='local *'.$package.'::'.$selfname.' = sub { $me };' if $Config->{options}->{subthis};  | 
| 
292
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.='local ${^_'.$selfname.'} = $me;' if $Config->{options}->{hatthis};  | 
| 
293
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$self.='local *'.$package.'::'.$selfname.' = \$me;' if $Config->{options}->{varthis};  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		#$self = 'my $me = $_[0]; local *'.$package.'::'.$self.' = sub { $me }; local ${^_'.$self.'} = $_[0]; local *'.$package.'::'.$self.' = \shift;'  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
296
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($class eq "_") {  | 
| 
297
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class = "";  | 
| 
298
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class.= 'local $_ = ref($me)||$me;' if $Config->{options}->{varthis};  | 
| 
299
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class.= 'local ${^__} = $me;' if $Config->{options}->{hatthis};  | 
| 
300
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class.= 'local $_ = ref($me)||$me;' unless $class;  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
302
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $classname = $class;  | 
| 
303
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class = 'my $class = ref($me)||$me;';  | 
| 
304
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class.='local *'.$package.'::'.$classname.' = sub { $class };' if $Config->{options}->{subclass};  | 
| 
305
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class.='local ${^_'.$classname.'} = $class;' if $Config->{options}->{hatclass};  | 
| 
306
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$class.='local *'.$package.'::'.$classname.' = \$class;' if $Config->{options}->{varclass};  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
308
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for (@args) {  | 
| 
309
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $aname = $_;  | 
| 
310
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 		if ($aname=~/^\@(\w+)$/ and $aname eq $args[-1]) {  | 
| 
311
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$aname = $1;  | 
| 
312
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_ = '';  | 
| 
313
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'local @{^_'.$aname.'} = @_;' if $Config->{options}->{hatargs};  | 
| 
314
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'my @args = @_; local *'.$package.'::'.$aname.' = \@args;' if $Config->{options}->{varargs};  | 
| 
315
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			next;  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
317
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 		if ($aname=~/^\%(\w+)$/ and $aname eq $args[-1]) {  | 
| 
318
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$aname = $1;  | 
| 
319
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_ = '';  | 
| 
320
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'local %{^_'.$aname.'} = @_;' if $Config->{options}->{hatargs};  | 
| 
321
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.= 'my %args = @_; local *'.$package.'::'.$aname.' = \%args;' if $Config->{options}->{varargs};  | 
| 
322
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			next;  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
324
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$aname=~s{^\$}{}; # Allow, but ignore leading dollar sigal.  | 
| 
325
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		unless ($aname=~/^\w+$/) {  | 
| 
326
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			require Carp;  | 
| 
327
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			local $Carp::CarpLevel = 1;  | 
| 
328
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			Carp::croak "Bad argument name: $aname (@args)";  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
330
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_ = ''; # This alters @args!  | 
| 
331
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		if ($aname eq '_') {  | 
| 
332
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.='local $_ = $_[0];';  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
334
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.='local ${^_'.$aname.'} = $_[0];' if $Config->{options}->{hatargs};  | 
| 
335
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			$_.='local *'.$package.'::'.$aname.' = \$_[0];' if $Config->{options}->{varargs};  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
337
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$_.='shift;';  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	Class methods don't get fields (you have the {this} variable).  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	my @fields = @{$Config->{fields}};  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	for (@fields) {  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		my $fname = $_;  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		$_ = "";  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		$_.='local ${^_'.$fname.'} = $me->{q('.$fname.')};' if $Config->{options}->{hatfields};  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		$_.='local *'.$package.'::'.$fname.' = \$me->{q('.$fname.')};' if $Config->{options}->{varfields};  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	}  | 
| 
347
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $proto = prototype $referent;  | 
| 
348
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (defined $proto) {  | 
| 
349
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$proto = "($proto)";  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} else {  | 
| 
351
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$proto = "";  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
353
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($Config->{options}->{debug}) {  | 
| 
354
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $subdecl = "sub ".$package."::".(*{$symbol}{NAME}).$proto." {\n\t$self\n\t$class\n\t@args\n\t\$referent->(\@_)\n};\n";  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
355
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		$subdecl=~s{;(?!\n)\s*}{;\n\t}gs;  | 
| 
356
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		warn $subdecl;  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
358
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	local $@;  | 
| 
359
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $subdecl = "package $package; sub $proto {  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		$self  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		$class  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		@args  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		\$referent->(\@_)  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	};";  | 
| 
365
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $subref = eval $subdecl;  | 
| 
366
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	die "Failure to create sub: ".$@."\n$subdecl" if $@;  | 
| 
367
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my ($sympkg,$symname) = (*{$symbol}{PACKAGE},*{$symbol}{NAME});  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	eval '*{$symbol} = $subref; 1' or warn "Assigning symbol: $@"; # I don't know why this doesn't work any more.  | 
| 
369
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	eval '$'.$sympkg.'::{$symname} = $subref' or die "Failed to assign symbol *{$symbol}{PACKAGE}::*{$symbol}{NAME}: $@";  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	*{$symbol} = eval "package $package; sub $proto {  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		$self  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		$class  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		@args  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		\$referent->(\@_)  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	};";  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our %Methods;  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our %ClassMethods;  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our %symcache;  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub findsym($$) {  | 
| 
383
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 	my ($pkg,$ref) = @_;  | 
| 
384
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	return $symcache{$pkg,$ref} if $symcache{$pkg,$ref} and *{$symcache{$pkg,$ref}}{CODE} eq $ref;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
385
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 	no strict 'refs';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
537
 | 
    | 
| 
386
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for (values %{$pkg."::"}) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
387
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 		return $symcache{$pkg,$ref} = $_ if *{$_}{CODE} and *{$_}{CODE} eq $ref;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
389
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return undef; # Don't cache incase there is a better way to get it later.  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub make_methods($);  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub make_methods($) {  | 
| 
394
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
 	my $pkg = shift;  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# My call line looks like this to maintain Attribute::Handlers compatibility.  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# unfortunately I cannot use Attribute::Handlers because it fails to trigger  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# if you do "eval 'use mypkg;'" and it can't find the symbols.  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	#my ($package, $symbol, $referent, $attr, $data, $stage);  | 
| 
399
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my @oa = $pkg->NEXT::ELSEWHERE::ancestors;  | 
| 
400
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	1 while @oa and shift(@oa) ne $pkg;  | 
| 
401
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	1 while @oa and shift(@oa) ne "Class::MethodVars::_ATTRS";  | 
| 
402
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $next;  | 
| 
403
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if (@oa) {  | 
| 
404
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		make_methods(shift(@oa));  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
406
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for my $data (@{$ClassMethods{$pkg}||[]}) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
407
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my ($package,$ref,$args) = @$data;  | 
| 
408
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $sym = findsym($package,$ref);  | 
| 
409
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		ClassMethod($package,$sym,$ref,"ClassMethod",$args,"import");  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
411
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for my $data (@{$Methods{$pkg}||[]}) {  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
412
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my ($package,$ref,$args) = @$data;  | 
| 
413
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		my $sym = findsym($package,$ref);  | 
| 
414
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		Method($package,$sym,$ref,"ClassMethod",$args,"import");  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
416
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	delete $ClassMethods{$pkg};  | 
| 
417
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	delete $Methods{$pkg};  | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
421
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 	no warnings 'void'; # "Too late to run INIT block"  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
118
 | 
    | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	INIT {  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		make_methods($_) for keys %ClassMethods;  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		make_methods($_) for keys %Methods;  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	};  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Class::MethodVars::_ATTRS;  | 
| 
429
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
    | 
| 
430
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
432
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use NEXT; # Need this incase they used to inherit from someone else.  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
745
 | 
    | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub import {  | 
| 
435
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
 	my ($spkg,@args) = @_;  | 
| 
436
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $tpkg = caller;  | 
| 
437
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	if ($spkg eq __PACKAGE__) {  | 
| 
438
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		require Carp;  | 
| 
439
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		Carp::croak "Don't do that.";  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
441
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	Class::MethodVars::make_methods($spkg);  | 
| 
442
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my @oa = $_[0]->NEXT::ELSEWHERE::ancestors;  | 
| 
443
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	1 while @oa and shift(@oa) ne $tpkg;  | 
| 
444
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	1 while @oa and shift(@oa) ne __PACKAGE__;  | 
| 
445
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $next;  | 
| 
446
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	if (@oa and $next = $oa[0]->can("import")) {  | 
| 
447
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		goto &$next;  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub MODIFY_CODE_ATTRIBUTES {  | 
| 
452
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
42
 | 
 	my ($pkg,$ref,@attrs) = @_;  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # I want to write this:  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	my @oldattrs = @attrs;  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	unless (eval q{ @attrs = $pkg->NEXT::DISTINCT::ACTUAL::MODIFY_CODE_ATTRIBUTES($ref,@attrs); 1 }) {  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #		@attrs = @oldattrs;  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	}  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # But "(eval)" can't call NEXT...MODIFY_CODE_ATTRIBUTES! So:  | 
| 
460
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	my @oa = $_[0]->NEXT::ELSEWHERE::ancestors;  | 
| 
461
 | 
1
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
43
 | 
 	1 while @oa and shift(@oa) ne caller;  | 
| 
462
 | 
1
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
5
 | 
 	1 while @oa and shift(@oa) ne __PACKAGE__;  | 
| 
463
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	my $next;  | 
| 
464
 | 
1
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
6
 | 
 	if (@oa and $next = $oa[0]->can("import")) {  | 
| 
465
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		@attrs = $pkg->$next($ref,@attrs);  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # End whinge  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
469
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	my @bad_attrs;  | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	my @good_attrs;  | 
| 
471
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	for (@attrs) {  | 
| 
472
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
10
 | 
 		if (/\A(?:Class)?Method(?:\(.*)?\z/) {  | 
| 
473
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 			push(@good_attrs,$_);  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
475
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			push(@bad_attrs,$_);  | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
478
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 	if (@good_attrs > 1) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
479
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		require Carp;  | 
| 
480
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		Carp::croak q{Please only use one of :Method or :ClassMethod for each method};  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	} elsif (@good_attrs) {  | 
| 
482
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 		my $args;  | 
| 
483
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 		$args = [split(/[\s,]/,$1)] if $good_attrs[0]=~/\((.*)\)\s*\z/;  | 
| 
484
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 		if ($good_attrs[0]=~/\AClassMethod/) {  | 
| 
485
 | 
1
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
9
 | 
 			$ClassMethods{$pkg}||=[];  | 
| 
486
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 			push(@{$ClassMethods{$pkg}},[ $pkg,$ref,$args ]);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		} else {  | 
| 
488
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 			$Methods{$pkg}||=[];  | 
| 
489
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 			push(@{$Methods{$pkg}},[ $pkg,$ref,$args ]);  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
492
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	return @bad_attrs;	  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Class::MethodVars::_Private;  | 
| 
496
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
6
 | 
 use warnings;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
    | 
| 
497
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
11
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
384
 | 
    | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub unique(@) {  | 
| 
500
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
6
 | 
 	my %u = map { $_=>$_ } @_;  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
501
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	return values %u;  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub retrFields($) {  | 
| 
505
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
2
 | 
 	my $pkg = shift;  | 
| 
506
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
 	return () unless $Class::MethodVars::Configs{$pkg};  | 
| 
507
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	return () unless $Class::MethodVars::Configs{$pkg}->{fields};  | 
| 
508
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
 	return @{$Class::MethodVars::Configs{$pkg}->{fields}};  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub findBaseFields($);  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub findBaseFields($) {  | 
| 
513
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
2
 | 
 	my $pkg = shift;  | 
| 
514
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
 	my @isa = eval '@'.$pkg.'::ISA';  | 
| 
515
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	my @fields;  | 
| 
516
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	for my $bpkg (@isa) {  | 
| 
517
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		push(@fields,findBaseFields($bpkg));  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
519
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	return unique @fields,retrFields $pkg;  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |