A codefile whose name is prefixed with “zz” can be one of two things. It's either a file that someone wanted to get rid of but was afraid to delete, or it's an intentional naming scheme to keep the file at the bottom as part of some crude code-organization technique. There used to be a third option - the file's a part of an application commissioned by a certain American rock trio known for their beards and cheap sunglasses - but the band dropped that requirement a long time ago.

However, when Mark Arnott stumbled across "zzGeneralFunctions.asp" as part of a maintenance project he was assigned, it was pretty clear why the file existed. Its first line contained the following comment:

' If you do something more than once, put it in a function here.

After a quick skim through the tens of thousands of lines of code, it was fairly obvious that, while the developers followed that "more than once" comment to the letter, they didn't follow the implied advice: before you put a function here, check if that function already exists. Take, for example, calculating a given month's name.

function MonthName(mNum)
	dim m
	on error resume next
	m=0
	MonthName="??"
	'if IsDate(mNum) then m=month(mNum)
	m=int(mNum)	
	if m=1 then MonthName="January"
	if m=2 then MonthName="February"
	if m=3 then MonthName="March"
	if m=4 then MonthName="April"
	if m=5 then MonthName="May"
	if m=6 then MonthName="June"
	if m=7 then MonthName="July"
	if m=8 then MonthName="August"
	if m=9 then MonthName="September"
	if m=10 then MonthName="October"
	if m=11 then MonthName="November"
	if m=12 then MonthName="December"
end function

Ignoring the fact that there's already a built-in VBScript function that does just that, and that the built-in function is also named MonthName, this code seems perfectly logical. In fact, so logical that it was repeated a few lines down.

function GetMonthName(thisNum)
	dim m
	on error resume next
	m=0
	GetMonthName="??"
	'if IsDate(thisNum) then m=month(thisNum)
	m=int(thisNum)	
	if m=1 then GetMonthName="January"
	if m=2 then GetMonthName="February"
	if m=3 then GetMonthName="March"
	if m=4 then GetMonthName="April"
	if m=5 then GetMonthName="May"
	if m=6 then GetMonthName="June"
	if m=7 then GetMonthName="July"
	if m=8 then GetMonthName="August"
	if m=9 then GetMonthName="September"
	if m=10 then GetMonthName="October"
	if m=11 then GetMonthName="November"
	if m=12 then GetMonthName="December"
end function

And then there was this function which did mostly the same thing, and also replaced the built-in functionality of VBScript's MonthName.

function MonthAbbr(m)
	on error resume next
	MonthAbbr="??"
	if IsDate(m) then m=month(m)
	if m=1 then MonthAbbr="Jan."
	if m=2 then MonthAbbr="Feb."
	if m=3 then MonthAbbr="Mar."
	if m=4 then MonthAbbr="Apr."
	if m=5 then MonthAbbr="May"
	if m=6 then MonthAbbr="Jun."
	if m=7 then MonthAbbr="Jul."
	if m=8 then MonthAbbr="Aug."
	if m=9 then MonthAbbr="Sep."
	if m=10 then MonthAbbr="Oct."
	if m=11 then MonthAbbr="Nov."
	if m=12 then MonthAbbr="Dec."
end function

The combinations and permutations of almost identically named and functioning date/time methods were astonishing. At some point, functions names started to end with a number. And then came the prefixes.

function zzFormatDate4(thisdate)
	dim tmp, m
	on error resume next
	tmp = ""
	if (IsDate(thisdate)) then
		m = month(thisdate)
		tmp = ""
		if m=1 then tmp="January"
		if m=2 then tmp="February"
		if m=3 then tmp="March"
		if m=4 then tmp="April"
		if m=5 then tmp="May"
		if m=6 then tmp="June"
		if m=7 then tmp="July"
		if m=8 then tmp="August"
		if m=9 then tmp="September"
		if m=10 then tmp="October"
		if m=11 then tmp="November"
		if m=12 then tmp="December"
		tmp = tmp & " "
		tmp = tmp & right("00" & day(thisdate),2)
		tmp = tmp & ", "
		tmp = tmp & year(thisdate)
	end if
	zzFormatDate4 = tmp
end function

By the time Mark got to zzFormatDate4, he just gave up looking. It was going to be a very long maintenance project.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!