line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Acme::Scurvy::Whoreson::BilgeRat; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
$VERSION = '1.0'; |
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
880
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
31
|
|
6
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
45
|
|
7
|
|
|
|
|
|
|
use overload ( |
8
|
1
|
|
|
|
|
11
|
'""' => \&stringify, |
9
|
|
|
|
|
|
|
fallback => 1 |
10
|
1
|
|
|
1
|
|
2588
|
); |
|
1
|
|
|
|
|
1282
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Acme::Scurvy::Whoreson::BilgeRat - multi-lingual insult generator |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
use Acme::Scurvy::Whoreson::BilgeRat; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
my $insultgenerator = Acme::Scurvy::Whoreson::BilgeRat->new( |
21
|
|
|
|
|
|
|
language => 'pirate' |
22
|
|
|
|
|
|
|
); |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
print $insultgenerator; # prints a piratical insult |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 DESCRIPTION |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
A multi-lingual insult generator, which takes pluggable backends to |
29
|
|
|
|
|
|
|
generate insults in the language of your choice, written in honour of |
30
|
|
|
|
|
|
|
International Talk Like A Pirate Day on Sept 19th 2003 |
31
|
|
|
|
|
|
|
L. An example backend is provided |
32
|
|
|
|
|
|
|
which implements the 'pirate' language. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
Usage is very simple. Instantiate an Acme::Scurvy::Whoreson::BilgeRat |
35
|
|
|
|
|
|
|
object, passing a single named parameter - 'language' - to the constructor. |
36
|
|
|
|
|
|
|
This tells it to use the A::S::W::B::Backend::[language] plugin module. |
37
|
|
|
|
|
|
|
If that is missing, we assume you want the 'pirate' backend. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
To generate an insult, simply mention your object in any place where it |
40
|
|
|
|
|
|
|
will be turned into a string. It uses the AWESOME POWER of operator |
41
|
|
|
|
|
|
|
overloading to achieve this heroic feat. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=cut |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub new { |
46
|
3
|
|
|
3
|
0
|
215
|
my($class, %params, $backend) = @_; |
47
|
|
|
|
|
|
|
|
48
|
3
|
100
|
33
|
|
|
42
|
die("Read the fucking manual you shitwit and at least use the constructor right!") |
49
|
|
|
|
|
|
|
if(!$class || join('', keys %params) !~ /^(language)?$/); |
50
|
|
|
|
|
|
|
|
51
|
2
|
|
100
|
|
|
11
|
$params{language} ||= 'pirate'; |
52
|
|
|
|
|
|
|
|
53
|
1
|
|
|
1
|
|
920
|
eval " |
|
1
|
|
|
1
|
|
3
|
|
|
1
|
|
|
|
|
17
|
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
12
|
|
|
2
|
|
|
|
|
174
|
|
54
|
|
|
|
|
|
|
use Acme::Scurvy::Whoreson::BilgeRat::Backend::$params{language}; |
55
|
|
|
|
|
|
|
"; |
56
|
2
|
50
|
|
|
|
7
|
$@ && die("Bollocks! I can't find a language backend for '$params{language}'"); |
57
|
|
|
|
|
|
|
|
58
|
2
|
|
|
|
|
11
|
$backend = "Acme::Scurvy::Whoreson::BilgeRat::Backend::$params{language}"->new(); |
59
|
2
|
50
|
33
|
|
|
140
|
($backend && $backend->isa("Acme::Scurvy::Whoreson::BilgeRat::Backend::$params{language}")) || |
60
|
|
|
|
|
|
|
die("For fuck's sake, the fucking backend's fucked"); |
61
|
|
|
|
|
|
|
|
62
|
2
|
|
|
|
|
7
|
$backend; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub stringify { |
66
|
4
|
|
|
4
|
0
|
6
|
my $self = shift; |
67
|
4
|
|
|
|
|
14
|
$self->generateinsult(); |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub generateinsult { |
71
|
4
|
|
|
4
|
0
|
6
|
my($self, %usedwords, $insult) = (shift); |
72
|
4
|
|
|
|
|
6
|
foreach my $element (split(//, $self->{grammars}->[rand @{$self->{grammars}}])) { |
|
4
|
|
|
|
|
53
|
|
73
|
9
|
|
|
|
|
10
|
my $word = ''; |
74
|
9
|
|
|
|
|
9
|
my $counter = 0; |
75
|
9
|
|
66
|
|
|
22
|
while(!$word || $usedwords{$word}) { |
76
|
4
|
|
|
|
|
7
|
$word = (uc $element eq 'N') ? $self->{nouns}->[rand @{$self->{nouns}}] : |
|
5
|
|
|
|
|
10
|
|
77
|
9
|
50
|
|
|
|
23
|
(uc$ element eq 'A') ? $self->{adjectives}->[rand @{$self->{adjectives}}] : |
|
|
100
|
|
|
|
|
|
78
|
|
|
|
|
|
|
die("The dickhead who wrote your backend fucked up"); |
79
|
9
|
50
|
|
|
|
44
|
return '' if(++$counter == 100); |
80
|
|
|
|
|
|
|
} |
81
|
9
|
|
|
|
|
15
|
$usedwords{$word} = 1; |
82
|
9
|
100
|
|
|
|
23
|
$insult .= (($insult) ? ' ' : '').$word; |
83
|
|
|
|
|
|
|
} |
84
|
4
|
|
|
|
|
35
|
$insult; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
=head1 PLUGINS |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
So, on to the most complex part of all this, which thankfully isn't that |
90
|
|
|
|
|
|
|
complex. |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
To create a plugin, you create a bog-standard module, whose name is |
93
|
|
|
|
|
|
|
Acme::Scurvy::Whoreson::BilgeRat::Backend::[your language name]. It should |
94
|
|
|
|
|
|
|
be a subclass of A::S::W::B. The constructor should return a blessed |
95
|
|
|
|
|
|
|
object and must be called new(). You then have two options: |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=over 4 |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=item use the built-in insult generator |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
In this case, you simply need to define a suitable grammar and list of |
102
|
|
|
|
|
|
|
words to generate insults from. You do this by having new() return |
103
|
|
|
|
|
|
|
a blessed hashref with the following keys: |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=over 4 |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item grammars |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
A reference to a list of strings, each of which is a grammar describing a |
110
|
|
|
|
|
|
|
valid way of constructing an insult, and may consist of the letters |
111
|
|
|
|
|
|
|
'A' and 'N'. A grammar is chosen at random when we generate an insult. |
112
|
|
|
|
|
|
|
For each part of the grammar, a random adjective is chosen for each 'A' and |
113
|
|
|
|
|
|
|
a random noun is chosen for each 'N'. |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=item nouns |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
A list of nouns. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=item adjectives |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
A list of adjectives. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=back |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
You may have words appearing in both the nouns and the adjectives lists. |
126
|
|
|
|
|
|
|
The default insult generator will ensure that it never uses the same word |
127
|
|
|
|
|
|
|
twice in any one insult. Of course, there are some situations where there |
128
|
|
|
|
|
|
|
are simply not enough nouns or adjectives in the grammar, in which case |
129
|
|
|
|
|
|
|
an empty insult is generated. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=item supply your own insult generator |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
In many cases, the default insult generator won't be sufficient for your |
134
|
|
|
|
|
|
|
language, as you may need to decline your nouns and adjectives or do other |
135
|
|
|
|
|
|
|
weird and wonderful manipulations. In this case, you need to override the |
136
|
|
|
|
|
|
|
generateinsult() method. This is a bog-standard method, which will be |
137
|
|
|
|
|
|
|
called with exactly one parameter - a reference to the object. You must |
138
|
|
|
|
|
|
|
return a string from this method. How you generate that string is entirely |
139
|
|
|
|
|
|
|
up to you, and you may need to do something different from what I have |
140
|
|
|
|
|
|
|
described above in the constructor. The only limitation on the constructor |
141
|
|
|
|
|
|
|
for a backend is that it *must* return something that inherits from A::S::W::B, |
142
|
|
|
|
|
|
|
and it will not be supplied with any parameters at all other than its own |
143
|
|
|
|
|
|
|
class name. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=back |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
See the A::S::W::B::Backend::pirate module for an example. |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=head1 BUGS |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
No bugs are known, but if you find any please let me know, and send a test |
152
|
|
|
|
|
|
|
case and - if possible - a patch. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=head1 FEEDBACK |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
I welcome feedback about my code, including constructive criticism. And, |
157
|
|
|
|
|
|
|
while this is free software (both free-as-in-beer and free-as-in-speech) I |
158
|
|
|
|
|
|
|
also welcome payment. In particular, your bug reports will get moved to |
159
|
|
|
|
|
|
|
the front of the queue if you buy me something from my wishlist, which can |
160
|
|
|
|
|
|
|
be found at L. |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
=head1 AUTHOR |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
David Cantrell EFE |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head1 COPYRIGHT |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Copyright 2003 David Cantrell |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
This module is free-as-in-speech software, and may be used, distributed, |
171
|
|
|
|
|
|
|
and modified under the same terms as Perl itself. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=cut |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
1; |