line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
2
|
|
|
2
|
|
49419
|
use strict; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
71
|
|
2
|
2
|
|
|
2
|
|
12
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
501
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Acme::Cat::Schroedinger; |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Acme::Cat::Schroedinger - objects whose behaviour is determined by attempts to inspect or interact with it. |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 VERSION |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
1 |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=cut |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = 1; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use overload ( |
19
|
0
|
|
|
0
|
|
0
|
'0+' => sub {return $_[0]->('0+')->($_[0]);}, |
20
|
3
|
|
|
3
|
|
11
|
'""' => sub {return $_[0]->('""')->($_[0]);}, |
21
|
1
|
|
|
1
|
|
9
|
'@{}' => sub {return $_[0]->('@{}')->($_[0]);}, |
22
|
2
|
|
|
2
|
|
6
|
'%{}' => sub {return $_[0]->('%{}')->($_[0]);}, |
23
|
1
|
|
|
1
|
|
5
|
'${}' => sub {return $_[0]->('${}')->($_[0]);}, |
24
|
0
|
|
|
0
|
|
0
|
'*{}' => sub {return $_[0]->('*{}')->($_[0]);}, |
25
|
2
|
|
|
2
|
|
3438
|
); |
|
2
|
|
|
|
|
2288
|
|
|
2
|
|
|
|
|
39
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub new{ |
29
|
8
|
|
|
8
|
1
|
3626
|
my $class = shift; |
30
|
8
|
|
|
|
|
19
|
my %options = @_; |
31
|
|
|
|
|
|
|
my $self = sub { |
32
|
8
|
|
|
8
|
|
17
|
my $attr = shift; |
33
|
8
|
|
|
|
|
30
|
my @caller = caller; |
34
|
8
|
100
|
|
|
|
28
|
return sub {'meow'} unless $caller[0] eq __PACKAGE__; |
|
1
|
|
|
|
|
423
|
|
35
|
7
|
|
|
|
|
34
|
my %attrs = ( |
36
|
|
|
|
|
|
|
'temperament' => 'cooperative', # cooperative | perverse | random |
37
|
|
|
|
|
|
|
'kittens' => 'inherit', # inherit | default | random |
38
|
|
|
|
|
|
|
'mutable' => '1', # 0 | 1 # never usable |
39
|
|
|
|
|
|
|
%options |
40
|
|
|
|
|
|
|
); |
41
|
7
|
50
|
|
|
|
19
|
return $attrs{$attr} if exists $attrs{$attr}; # check caller |
42
|
7
|
100
|
66
|
|
|
37
|
my $coopRef = ($attrs{temperament} eq 'cooperative' or ($attrs{temperament} eq 'random' and int(rand(2)) ) )? undef:''; |
43
|
0
|
0
|
|
|
|
0
|
my %overload = ( |
44
|
|
|
|
|
|
|
'0+' => sub {return ($_[0]= defined $coopRef?die:0);}, |
45
|
3
|
100
|
|
|
|
27
|
'""' => sub {return ($_[0]= defined $coopRef?die:'');}, # todo: include temperament |
46
|
1
|
|
50
|
|
|
11
|
'@{}' => sub {return ($_[0]=$coopRef // []);}, # todo: include temperament |
47
|
2
|
|
100
|
|
|
18
|
'%{}' => sub {return ($_[0]=$coopRef // {});}, # todo: include temperament |
48
|
1
|
|
50
|
|
|
9
|
'${}' => sub {return ($_[0]=$coopRef // \0);}, # todo: include temperament |
49
|
0
|
|
0
|
|
|
0
|
'*{}' => sub {return ($_[0]=$coopRef // \*{''});}, # todo: include temperament |
|
0
|
|
|
|
|
0
|
|
50
|
7
|
|
|
|
|
93
|
); |
51
|
7
|
|
|
|
|
83
|
return $overload{$attr}; |
52
|
8
|
|
|
|
|
49
|
}; |
53
|
8
|
|
|
|
|
79
|
bless $self, $class; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 SYNOPSIS |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
A newly-created Acme::Cat::Schroedinger could be anything. It could be cooperative, and be anything you want it to be. It could be perverse and will never be what you want it to be. Or it could behave like the original Schroedinger's Cat and its behaviour will be, for all intents and purposes, unknowable until you interact with it. |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
my $cat = Acme::Cat::Schroedinger->new(); |
61
|
|
|
|
|
|
|
print %{$cat}; # The cat is now an empty hashref, and does not die. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# or... |
64
|
|
|
|
|
|
|
my $cat = Acme::Cat::Schroedinger->new(temperament=>'perverse'); |
65
|
|
|
|
|
|
|
print %{$cat}; # The cat is guaranteed not to be a hashref (or anything else you expect it to be), and thus will die. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# or... |
68
|
|
|
|
|
|
|
my $cat = Acme::Cat::Schroedinger->new(temperament=>'random'); |
69
|
|
|
|
|
|
|
print %{$cat}; # May or may not die, the only way of knowing is running the code. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=head1 DESCRIPTION |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
The Acme::Cat::Schroedinger can be 'observed' in various ways by being treated like a hashref or an arrayref or a string. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Note that once you have observed the cat, it typically ceases to be a cat: the experiment is no longer repeatable. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head2 METHOD new |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
my $cat = Acme::Cat::Schroedinger->new(); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
When you create the cat, it has the following properties: |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=head3 temperament = cooperative |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
Allowed: C. Determines whether the cat always behaves the way you ask it to, never behaves the way you ask it to, or decides how to behave only when you ask it. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=head1 BUGS |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
If you're clever, you can work out that the object in question is a cat, and furthermore you might be able to work out its temperament, mutability, etc. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=cut |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
1; |