File Coverage

blib/lib/Acme/Scurvy/Whoreson/BilgeRat.pm
Criterion Covered Total %
statement 38 38 100.0
branch 10 14 71.4
condition 6 11 54.5
subroutine 8 8 100.0
pod 0 3 0.0
total 62 74 83.7


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;