<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Namegame.pm module
#########################################################+
#      From the CONSULTIX "Perl Programming" class      #+
# POB 70563, Seattle WA 98107 USA tim@consultix-inc.com #+
#  Copyright 1997-2001, Tim Maher. All Rights Reserved  #+
#########################################################+
# Tim Maher, tim@teachmeperl.com

package	Lingua::EN::Namegame;

use 5.006;	# 5.6.0 needed for "our" keyword
use strict;
use warnings;
use Carp;

require	Exporter;

our @ISA		=	qw(Exporter);
our @EXPORT		=	qw(name2verse);
our @EXPORT_OK		=	qw( );
our $VERSION		= 	'0.02';

our ($SEP);

# name_game
# A program that generates a rhyming verse from a name,
# as in the famous song "The Name Game", by Shirley Ellis

# Inspired by "One-Liner #40", in TPJ #15, Fall 1999, p. 11.
#  by Sean M. Burke:
#   s&lt;^([bcdfghjklmnpqrstvwxyz]*)(\w+).*&gt;
#   &lt;$1$2 $1$2 $1o $1$2 / Bonana-Fanna-Fo-F$2 / Fe Fi Mo M$2 / $1$2!&gt;i;

# Reworked by Tim Maher to comply with the
# rhyming rules of the song, as documented in 
# http://www.geocities.com/SunsetStrip/Palladium/1306/shirley.htm.

# GENERAL RULES:
# 1) Say the name twice 
#	"Dave  Dave"

# 2) Say "bo" and Name again, replacing Name's first letter by B
#	"Bo Bave"

# 3) Say Banana Fanna Fo Name, replacing Name's first letter by F
#	"banana Fanna Fo Fave"

# 4) Say Fee Fi Mo Name, replacing Name's first letter by M
#	"Fee Fi Mo Mave"

# 5) Say Name once more 
#	"Dave"


# ALTERNATE RULES, for Names Starting with B, F, or M
#   (e.g., Marsha)
# 2. B-names; instead of bo Bob, use Bo-ob
# 3. F-names; instead of Banana Fanna Fo Fred
#    -- Banana Fanna Fo-red
# 4. M-names; instead of Fee Fi Mo Marsha -- Fee Fi Mo-arsha


sub name2verse {

	my $name=shift;	# grab the name for making the verse
	my ($f, $s, $i, $rest, $verse);

	# need &gt;= two word-chars, including one vowel
	unless ( defined $name  and
			$name =~ /[a-z][a-z]/i  and 
				$name =~/[aeiouy]/i ) {
		carp 'name2verse(): Name needs ',
			'two or more letters ',
			"including one vowel\n";
		return undef;
	}

	local $SEP="\n";	# meant to leak into sub indent() below
	# /^([bcdfghjklmnpqrstvwxyz]*)([a-zA-Z]+)/ 

	# Grab leading consonants (if present), and following vowels

	$name =~ /^\s*([b-df-hj-np-tv-z]*)([a-z]+)/i  or  return undef;

	$f="\u$1";	# force upper-case; "first" part (includes initial)
	$s="\L$2";	# force lower-case; "second" part
	$i=substr($f,0,1);	# force upper-case; "initial"
	$f ne '' and
		$rest=substr($f,1) . $s;	# "rest" of first part

	#print "I, rest, F, S = $i, $rest, $f, $s\n";
	# print "Using rule #2, for $f/$s\n";

	# Now construct the verse for this name

	# Rule #1: State name twice
	$verse="\u$f$s \u$f$s " . indent();

	# Rule #2: General Case; Rob -&gt; Bo-Bob
	if ($i ne 'B') {
		$verse.="bo \uB$s, " . indent();
	}
	# Rule #2: Special Case For B-names; Bob -&gt; Bo-ob
	else {
		$verse.="${i}o-$rest, " . indent();
	}

	# Rule #3: General Case; Tom -&gt; Fo-Fom
	if ($i ne 'F') {			# Fo Fom
		$verse.="Banana Fanna Fo F$s, " . indent();
	}
	# Rule #3: Special Case for F-names; Fred -&gt; Fo-red
	else {
		$verse.="Banana Fanna ${i}o-$rest, " . indent();
	}
	# Rule #4: General Case; Tom -&gt; Mo-Mom
	if ($i ne 'M') {
		$verse.="Fee Fi Mo M$s\n\t";
	}
	# Rule #4: Special Case for M-names; Marsha -&gt; Mo-arsha
	else {
		$verse.="Fee Fi Mo-$s\n\t";
	}
	$verse.="\U$f$s!";
	return $verse;
}
sub indent { return ${SEP}.=' '; }
1;

__DATA__

=pod

=head1 NAME

Lingua::EN::Namegame - Creates a "Name-Game" verse from a name (or word)

=head1 VERSION

This document describes version 0.02 of Lingua::EN::Namegame,
released December 28, 2002.

=head1 SYNOPSIS

	use Lingua::EN::Namegame;

	$verse = name2verse ('Marsha');

	print $verse;

I&lt;Or, more simply, at your OS command prompt&gt;:

	name2verse.pl  Marsha		# script provided with module

=head2 Output

	Marsha Marsha 
	    bo Barsha, 
		Banana Fanna Fo Farsha, 
		    Fee Fi Mo-arsha
			MARSHA!

I&lt;Or, for extra policital correctness&gt;

	name2verse_nonprofane.pl  Bart	# script provided with module

=head2 Output

	Sorry, the verse for Bart contains a profane word.

=head1 DESCRIPTION

=head2 Purpose

B&lt;name2verse&gt;
is a subroutine that generates a rhyming verse based on a name (or word),
in accordance with the L&lt;rhyming algorithm&gt; documented in the lyrics of the
famous 1960's song B&lt;The Name Game&gt;, by I&lt;Shirley Ellis&gt;.



=head2 Background

A presentation based on this program was featured as a I&lt;Lightning Talk&gt;
at the North American B&lt;Yet Another Perl Conference&gt; (B&lt;YAPC::NA&gt;) 
in St. Louis MO, USA, on 6/28/2002.

Thanks to the foresight of the moderator (B&lt;MJD&gt;),
the presentation was scheduled as the I&lt;last one&gt; for the day,
providing us ample time to delve into extra-curricular shenanigans after the technical
part of the presentation.

And few present will ever forget the spine-tingling effect of
B&lt;300+ deranged Perl fanatics&gt; giving song to the
rhyming verses for various Perl I&lt;built-in functions&gt;,
including B&lt;map&gt;, B&lt;grep&gt;, B&lt;split&gt;, and of course, the
especially euphonious B&lt;wantarray&gt;:

	Wantarray Wantarray
	    bo Bantarray, 
		Banana Fanna Fo Fantarray, 
		    Fee Fi Mo Mantarray
			  WANTARRAY!

Notice the way this oddly chosen function name smoothly metamorphoses into a denizen of the deep
in the penultimate line!

And some thought Larry had goofed up by not calling it B&lt;wantlist&gt; instead.  I&lt;Poppycock!&gt;

=head2 Profanity Issues

Hey, that's not a bad word itself; let's try it!

	Poppycock Poppycock
	    bo Boppycock, 
		Banana Fanna Fo Foppycock, 
		    Fee Fi Mo Moppycock
		      POPPYCOCK!

Which reminds me that some actual human names, such as B&lt;Bart&gt; and especially B&lt;Chuck&gt;,
give rise to B&lt;really rousingly ribald rhymes&gt;, which has often led to embarassing outbursts of
I&lt;blushing and snickering&gt; in
our
Perl training classes.  One solution is to use the 
supplied
B&lt;name2verse_nonprofane.pl&gt; script to identify and filter-out verses that are
judged to contain profane words.
It does this through use of the "profanity matching regex" of I&lt;Damian Conway's&gt; B&lt;Regexp::Common&gt; module.


=for comment =head1 RHYMING_ALGORITHM

=head1 RHYMING ALGORITHM

This program was inspired by "One-Liner #40", in B&lt;The Perl Journal&gt; #15, Fall 1999, p. 11.,
by I&lt;Sean M. Burke&gt;,
which used a simplified version of the algorithm for succinctness:

 s&lt;^([bcdfghjklmnpqrstvwxyz]*)(\w+).*&gt;
    &lt;$1$2 $1$2 $1o $1$2/Bonana-Fanna-Fo-F$2/Fe Fi Mo M$2/$1$2!&gt;i;

In contrast, this module aims to comply with the actual rhyming rules of the song, as documented in
L&lt;http://www.geocities.com/SunsetStrip/Palladium/1306/shirley.htm&gt;.

=for comment
(In this regard, I recently made a change 
to give better results for names containing B&lt;Y&gt;s, such as B&lt;Lydia&gt; and B&lt;Lyle&gt;.)

=head2 General Rules

=over

=item 1. Say the Name twice (following examples using "Dave")

	-&gt; "Dave Dave"


=item 2. Say "bo" and Name again, replacing Name's first letter by B

	-&gt; "Bo Bave"

=item 3. Say "Banana Fanna Fo" Name, replacing Name's first letter by F

	-&gt; "banana Fanna Fo Fave"

=item 4. Say "Fee Fi Mo" Name, replacing Name's first letter by M

	-&gt; "Fee Fi Mo Mave"

=item 5. Finally, exclaim Name

	-&gt; "Dave!"

=back

=head2 Alternate Rules

Modified versions of rules 2-4 apply to Names starting with B&lt;B&gt;, B&lt;F&gt;, or B&lt;M&gt;.

=over

=item 2. B&lt;B&gt;-names:

say "Bo" and then Name without the initial B:

	-&gt; "Bo-ob" (for Bob)
	-&gt; "Bo-rian" (for Brian)
	-&gt; "Bo-lanche" (for Blanche)

=item 3. B&lt;F&gt;-names:

instead of "Banana Fanna Fo" Fred:

	-&gt; "Banana Fanna" B&lt;Fo-red&gt;

=item 4. B&lt;M&gt;-names:

instead of "Fee Fi Mo" Marsha:

	-&gt; "Fee Fi" B&lt;Mo-arsha&gt;

=back

=head1 BUGS

Please let me know if you find any bugs.

=head1 EXPORTS

name2verse()

=head1 SCRIPTS

B&lt;name2verse.pl&gt;, B&lt;name2verse_nonprofane.pl&gt;

=head1 AUTHORS

=for man
.nf
\fBTim Maher\fP
\fICEO\fP, \fBConsultix\fP
yumpy@cpan.org
http://www.teachmeperl.com
.fi

=for html
&lt;B&gt;Tim Maher&lt;/B&gt;&lt;BR&gt;
&lt;I&gt;CEO&lt;/I&gt;, &lt;B&gt;Consultix&lt;/B&gt;&lt;BR&gt;
yumpy@cpan.org&lt;BR&gt;
&lt;A HREF="http://www.teachmeperl.com"&gt;http://www.teachmeperl.com&lt;/A&gt;&lt;BR&gt;

=for text
Tim Maher
CEO, Consultix
yumpy@cpan.org
http://www.teachmeperl.com

=head1 SEE ALSO

L&lt;http://www.geocities.com/SunsetStrip/Palladium/1306/shirley.htm&gt;

=head1 LICENSE

=for html Copyright &amp;copy; 2002, Timothy F. Maher.  All rights reserved. 

=for roff Copyright \(co 2002, Timothy F. Maher.  All rights reserved. 

=for text Copyright (c) 2002, Timothy F. Maher.  All rights reserved. 

This module is free software;
you can redistribute it and/or modify it under the same terms as Perl itself.

=for comment Meant to be hidden now:
See (L&lt;http://www.perl.com/perl/misc/Artistic.html&gt;) and
(L&lt;http://www.gnu.org/copyleft/gpl.html&gt;) for details.

=cut

1;
</pre></body></html>