Programming Niches

All of my life, I’ve seen programmer after programmer; all of them have their own styles and methods of working. Some of these practices are good and beneficial to the program in general, some are purely aesthetic for said programmer and kill off performance. You can tell a lot about a person from the ways they format their code. So tell me, Facepunch, how do you program? What niches do you have?

Here’s some info about my habits:
When I make big projects that need global access, I use a global table (like the module system, for instance) that contain all of my
I choose to tabulate every line for organization. I can’t read script unless it’s tabulated. I mean, seriously, how could you not do it? Python requires you to tabulate your code; it’s what it uses for block detection, like Lua’s if/then and end, i.e.
[lua]
function ThisIsAFunction()
print(“Tabs!”)
local Blah = function(fawnk)
fawnk()
end
Blah(function()
print(“Hey, sup”)
end)
end
[/lua]
I also do not use the extra additions to the language that Garry has provided for our usage, should we see fit; this is Lua, and as such, I want my code to be Lua. Do not want !=, /**/, etc, kthx.
When I program in bracket-based languages (like C/++, Java, etc) I always put the brackets on their own lines, i.e.



public class Brackets
{
    public static int main(String Args[])
    {
        System.out.println("Code!");
        ...
        return 0;
    }
}


This is a really cool thread, I think anyway. I don’t want to post an example because I feel it won’t be exact to my style. Soo I’m just going to post this which I scripted yesterday, I notice that my style is really inconsistent but anyway what do you think? It’s not like how you do it, keeping lua all to lua, i make use of pretty much every c++ operator garry has added instead of the lua variants. Just habbit really.

[lua]
require(“glon”);

TreeSauce.characters = {};

if ( SERVER ) then

– Get a players characters, returns false if they have no characters.
function TreeSauce.characters.GetPlayerCharacters(player)
if ( !player.characters && !player:GetPData(“Characters”) ) then
return false;
end;

if ( player.characters ) then
	return player.characters;
else
	return glon.decode( player:GetPData("Characters") );
end;

end;

– Load the saved version of their characters.
function TreeSauce.characters.LoadSavedCharacters(player)
if ( player:GetPData(“Characters”) ) then
player.characters = glon.decode(player:GetPData(“Characters”));

	for name,data in pairs( player.characters ) do
		if ( data.inventory ) then
			
			local oldInvData = data.inventory;
			local oldMaxWeight = data.weight;

			player.characters[name].inventory = TreeSauce.container:Create();
			player.characters[name].inventory:SetMaxWeight(oldMaxWeight);
			player.characters[name].inventory:OverrideInventory(oldInvData);
		end;
	end;
end;

end;

– Save the characters table, if an override is given
function TreeSauce.characters.SavePlayerCharacters( player, override )
if ( !player.characters ) then
if ( !override ) then return; end;
end;

local charlist;

if ( override ) then
	charlist = override;
else
	charlist = player.characters;
end;

for k,v in pairs( charlist ) do
	if ( v.inventory ) then
		v.inventory = v.inventory:GetInventoryList();
	end;
end;

local charlistenc = glon.encode(charlist);

player:SetPData( "Characters", charlistenc );

end;

– Create a new character.
function TreeSauce.characters.PlayerCreateCharacter( player, sGender, sModel, sNameFirst, sNameLast, sDescription )
if ( !player ) then return; end;
if ( !sGender ) then return; end;
if ( !sModel ) then return; end;
if ( !sNameFirst ) then return; end;
if ( !sNameLast ) then return; end;
if ( !sDescription ) then return; end;

if ( !player.characters ) then
	player.characters = {};
end;

local nameFull = sNameFirst .. " " .. sNameLast;
local data = {};

data.gender = sGender;
data.model = sModel;
data.description = sDescription;
--data.inventory = {};

player.characters[nameFull] = data;

TreeSauce.characters.SavePlayerCharacters(player);

end;

– Delete a character
function TreeSauce.characters.Delete( player, character )
if ( !player or !character ) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

player.characters[character] = nil;

TreeSauce.characters.SavePlayerCharacters(player);

-- This is where we want to check if they were logged onto that character, and if they were display a notification and then the selection menu.

end;

– Set a characters model.
function TreeSauce.characters.SetCharacterModel( player, character, model )
if ( !player or !character or !model ) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

player.characters[character].model = model;

TreeSauce.characters.SavePlayerCharacters(player);

-- this is where we check if they are logged in, and if they are set their player entities model, UNLESS THEY ARE WEARING CLOTHING( update this when we add it ).

end;

– Get a characters model.
function TreeSauce.characters.GetCharacterModel( player, character )
if ( !player or !character ) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

return player.characters[character].model;

end;

– Set a characters description.
function TreeSauce.characters.SetCharacterDescription( player, character, description )
if ( !player or !character or !description ) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

player.characters[character].description = description;

TreeSauce.characters.SavePlayerCharacters(player);

end;

– Get a characters description
function TreeSauce.characters.GetCharacterDescription( player, character )
if ( !player or !character ) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

return player.characters[character].description;

end;

– Change a characters name, now this should probably be restricted to admin access.
function TreeSauce.characters.ChangeCharacterName( player, character, newfirst, newlast )
if ( !player or !character or !newfirst or !newlast) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

local copy = player.characters[character];
local nameFull = newfirst .. " " .. newlast;

player.characters[nameFull] = copy;
player.characters[character] = nil;

TreeSauce.characters.SavePlayerCharacters(player);
TreeSauce.characters.ClientRequestLocalCopy( player, nameFull);
TreeSauce.characters.DeleteCharacterLocalCopy( player, character );

-- If they are logged in you might have to change some shit, best keep this to a hook. when i make the login make sure to call it only if they are on that char, no point otherwise.
TreeSauce.characters.OnNameChange(player,character,nameFull);

end;

– This is the hook incase we need to update a player after a name change,while they are logged in.
function TreeSauce.characters.OnNameChange( player, old, new )
if ( player.alias == old ) then
player.alias = new;
player:SetModel( player.characters[new].model );
end;
end;

– Activate a character for use.
function TreeSauce.characters.Login( player, character )
if ( !player or !character ) then return; end;
if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;

if ( !player.characters ) then
	TreeSauce.characters.LoadSavedCharacters(player);
end;

if ( !player.characters[character] ) then return; end;

local data = player.characters[character];

player.alias = character;
player:SetModel( data.model );
-- other data will probably be sent here, just saying for now.

TreeSauce.characters.OnCharacterLogin( player, character );

end;

– an event for when they login to their character, handle data etc. here
function TreeSauce.characters.OnCharacterLogin( player, character )
end;

– Called when a client wants his local version of his client data updated.
function TreeSauce.characters.ClientRequestLocalCopy( player, character )
if ( !player.characters ) then return; end;
if ( !player.characters[character] ) then return; end;

local charlist = glon.encode(player.characters[character]);

umsg.Start( "ClientRequestCharacterListLocalCopy", player )
	umsg.String( character );
	umsg.String( charlist );
umsg.End();

end;

– delete a local copy of a character table.
function TreeSauce.characters.DeleteCharacterLocalCopy( player, character )
if ( !player or !character ) then return; end;

umsg.Start( "DeleteCharacterLocalCopy", player )
	umsg.String(character);
umsg.End();

end;

– so the client can request local copies by themselves
concommand.Add( “TreeSauce_RequestCharacterListLocalCopy”, function( player, command, arguments )
if ( !arguments[1] ) then return; end;

TreeSauce.characters.ClientRequestLocalCopy( player, arguments[1] );

end);

end;

if ( CLIENT ) then

TreeSauce.characters.LocalData = {};

usermessage.Hook( "DeleteCharacterLocalCopy", function( bfr )
	local character = bfr:ReadString();
	
	if ( !TreeSauce.characters.LocalData[character] ) then return; end;
	
	TreeSauce.characters.LocalData[character] = nil;
end);

usermessage.Hook( "ClientRequestCharacterListLocalCopy", function( bfr )

	local key = bfr:ReadString();
	local copy = bfr:ReadString();
	
	TreeSauce.characters.LocalData[key] = glon.decode(copy);
end);

end;

[/lua]

Kthx.

I feel that way a little, but my style is pretty consistent. I feel confident you could tell it was me that programmed something because I always use proper grammar when I name my variables, proper casing (though I camelCase in Java) and my own methods of tabbing/newlines/etc.

To be honest?
I really just plain hate your style. No offence or anything, to each his own. But really.

  1. The semicolons aren’t required at all. Actually, you can use newlines, spaces, semicolons, commas, etc to separate instructions in Lua. In some cases they aren’t even needed, ex.
    [lua]print(“Hello, world!”)print(“No spaces or anything needed, since the last character was a parenthesis;
    no possible instruction could be added to that parenthesis, so it also functions as a delimiter.”)[/lua]
    …though I think that looks ugly and the only time I use such things are when I’m trying to save space.
  2. You haphazardly add space padding to your parenthetical statements. I understand this makes code easier to read to some, but to me it makes it harder. Your eyes have to move farther to read the same amount of information. I don’t like it at all.
  3. So many newlines! I only make newlines to end statements and separate chunks of code, such as functions. Only in the global scope, though.
  4. Comments. I don’t use comments. Ever. Unless I’m trying to make a tutorial and add in little notes to assist the person reading it. If I can’t remember what I was working on enough to warrant a comment, I probably shouldn’t be doing it.
  5. You place parenthesis where they aren’t really needed, like in your if statements. I understand how this can make the code easier to read, and it’s required by a lot of languages (ex. Java) but I find it to be ugly when programming in Lua.

However…

  1. You use a global table to store your data. When dealing with a lot of stuff that’s a very good practice to have. It can impact speed slightly, having to constantly access a table, but it keeps things organized and you don’t clutter the global scope with unnecessary functions that could easily be overwritten by another dumb programmer.
  2. Your code seems generally good besides the fact that you could save space by compacting some of those if statments, ex.
    [lua]
    if ( !player or !character ) then return; end;
    if ( !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;
    [/lua]
    …becomes…
    [lua]
    if ( !player or !character or !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;
    [/lua]
    …proven in my Lua prompt…


Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> test1 = "test"
> test2 = {test = "test"}
> print(test1, test2, test2.test)
test    table: 00276318 test
> 
> test2 = nil
> 
> if not test1 or not test2 then print("Not 1!") end
Not 1!
> 
> if test2.test:upper() ~= "TEST" then print("Not 2!") end
stdin:1: attempt to index global 'test2' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?
>
> 
> if not test1 or not test2 or test2.test:upper() ~= "TEST" then print("Not 3!") end
Not 3!
> 


I bet you’re thinking that last one should have errored, am I right? The thing about Lua’s if statements is that they are linear; if any of the statements in the if statement are false, it will not even compute any of the remaining pieces of code, because even if they were true, one of the required statements was false.
You could also possibly try using conditional statements, instead of all the return ends (though they can’t really be used effectively with functions). Here is an example of them:



Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> test1 = 10
> test2 = 30
> 
> test3 = test1 == 10 and test2 or test1
> print(test3)
30
> 
> test1, test2, test3 = nil, 20, nil
> 
> test3 = test1 or test2
> print(test3)
20
>


[editline]asd[/editline]

Whoa I just realized this is really tl;dr.

You missed the end to close the function when you call Blah. Programming with style is cool, but the syntax has to be correct, also.

Herp derp. I wrote that in the response itself, just as means of example. Thanks for pointing that out, anyway.

[editline]13th May 2012[/editline]

For some reason, though, I felt something was wrong when I typed that. I didn’t really care at the time or something, I guess.

I tabulate everything too, it does make everything so much easier to read.

I also space my code out a lot, blank likes between anything that isn’t directly related, and spaces between all brackets (both (), and {})

eg
[lua]
foo( 1, “hi”, t[ 12 ], { “a”, “b”, “c” } )
[/lua]

Also, the previous point about combining the two return statements:
[lua]if ( !player or !character or !TreeSauce.characters.GetPlayerCharacters(player) ) then return; end;[/lua]

Personally, I would do that, UNLESS it made the line too long to fit in my editor, if it did then I’d split it up.

I also avoid using garrys C++ additions and I don’t use semicolons in Lua.

I do the same as you in C++ too, with brackets on new lines.

I don’t understand why some people don’t. I can’t read code worth anything without them.

I don’t use it because it mucks up my ability to read it. Probably because I’m just used to it.

I lol’d at that. Silly reason but valid nonetheless.
It doesn’t make as much of a difference performance-wise, but I try to cut all the corners I can, style be damned.

I don’t even know why he added them, for his own personal use? Why use non-Lua syntax in Lua?

I dunno why I do it, either, it takes up space but looks pretty to me.

[editline]13th May 2012[/editline]

Lua tag <3

Something I don’t get is why people do this :

[Lua]
if ( x > 1 ) then return x else return DEFAULT_VALUE end
[/Lua]

instead of

[Lua]

return ( x > 1 and x or DEFAULT_VALUE )

[/LUA]

Ohohoho.

But, I agree. It’s really quite silly. I know I certainly could use it more… Except many of the times I could use it would end up making things way too overcomplicated and memory-consuming. Sometimes it’s just simpler to use ifs.

I’m sure this is going to turn into a “Correct the lua of the person above you” thread ^^

I corrected your Lua.
Hurrrrrr.

[editline]13th May 2012[/editline]

It’s amazing the difference in style you people have, though. I follow the norm with only slight variances that make my code what it is.

It’s only in German where you need to capitalize the first letter of a noun, even if it’s a regular noun.

I agree. I, personally like to put everything in tables.

It’s easy to scroll up-down (mouse wheel) but more tedious to scroll left-right (have to move mouse to bottom of screen, get little draggy thing, move it across etc). When I’m scanning through my code to make sure I haven’t done anything stupid or missed a capital letter or something, it’s easier, I can read a whole page without having to fiddle around moving it.

I think it’s because when he’d been sat there coding C++ for ages, and suddenly needed to do something in Lua, if he accidentally used the C++ syntax he was used to, it wouldn’t matter.

I like your programming style, it looks exactly like mine. I can’t stand people who use C syntax in Lua, like unnecessary parentheses in if/while structures, useless semicolons, and C logical operators and comments. I also hate whitespace abuse, where expressions look like test1 = ( test2 + ( test3 * func ( test4 , test5 ) ) - test6 ). That’s bloody unreadable.

There’s just a major flaw in my coding, I always forget to use a global table to store my variables. I know that’s what I should do but I just keep forgetting it and just declare ugly global variables everywhere.

I don’t think that’s a valid excuse, I’ve been coding C++ for about years before learning Lua. A programmer needs to adapt to the language they’re using, not the opposite.

Can’t agree more, “it’s a habit” really isn’t much of an excuse.
…although I admittedly do use the C style comments purely because they’re faster to type and mess with.

I have a pretty inconsistent style, but I think it’s mostly fine. I like to use the Lua comments and operators as well.
[lua]function GM:LoadMapSetup( )

local values = {}
local s = file.Read("surf/"..game.GetMap()..".txt")
local lines = string.Explode("

", s)
local curkey = “”

for linenum, line in pairs( lines ) do

	if( line:sub(-1,-1) == ":" ) then
		
		curkey = line:sub(1, -2)
		values[curkey] = {}
		
	else
	
		line = string.Explode("=", line)
		local key, value = line[1]:gsub(" ", ""), line[2]
		if( value and value:sub(1,1) == " " ) then
			value = value:sub(2)
		end
		
		if( value and value:find( "," ) ) then
			-- it's an array of things
			value = value:gsub("[{}%s]", "")
			value = string.Explode(",",value)
			
		end
		
		if( value ) then
		
			value = tonumber(value) or value
			values[curkey][key] = values[curkey][key] or {}
			local n = #values[curkey][key]
			values[curkey][key][n+1] = value
			
		end
		
	end
	
end

return values

end[/lua]

as I messed with GLua more my style changed a lot, now it’s fairly consistent

[lua]local tblSpawns = {
Vector( 0, 0, 0 ),
Vector( 30, 100, 0 ),
}
hook.Add( “InitPostEntity”, “gm_SpawnAmmo”, function( )
if( game.GetMap( ) != “rp_downtown_v2pgs” ) then return; end
for i=1,#tblSpawns do
local v = tblSpawns*; – notice how there’s no spaces around the i
local objEnt = ents.Create( “ammo_crate” );
objEnt:SetPos( v );
objEnt:SetAngles( Angle( 0, 90, 0 );
objEnt:Spawn( );
end
end );[/lua]

Just something I wrote now, but that’s pretty much my style. I’ll find something better and post it later.

The more I use Lua, the less my code looks like Java which is my other strong language. I think it’s pretty cool because I know I’m writing in a completely different language and my coding style is changing to take advantage of what Lua has to offer. It sucks though because when I go back to coding in Java I start getting annoyed because it simply isn’t as flexible as Lua (give me back my first class functions >:( ), but it is a lot easier to write because that language is built to hold your hand. With that said, I’m finding it hard to let go of the C-style operators because they feel nicer to use.

Anyway my latest thing has been to start abusing tables because they’re the most useful data structures I’ve ever come across. Assign anything to ANYTHING? I can pretend that it’s an OBJECT?! AND I get to use it like an array too?! I’LL TAKE 20.

I also like abusing tabs; lining up all of the assignments makes things look neater to me. I can just look down a line of assignment operators to get to the one I want instead of looking back and forth.

[lua]
/*
This file defines functions for loading from and saving to Holopad project files.

Made with Bub!

*/

require “glon”
include(“modelviewer/obj_cl_PRJObject.lua”)

HoloProjectFile = {}
local this = HoloProjectFile

function this:Save( rendercoll, filename )

local holos, clips 	= this:RCollToTables(rendercoll)
local savefile 		= file.Open("holopad/"..filename..".txt", "w", "DATA")

if !savefile then return false end

status = pcall( function()
					savefile:Write( "HOLOPAD PRJ "..PRJObject.version.."

" )
savefile:Write( glon.encode(holos) )
savefile:Write( "
BEGIN CLIPS
" )
savefile:Write( glon.encode(clips) )
end )

if !status then
	Error("Unable to save the Holopad project; error writing a holo to file!")
	return false
end

savefile:Close()

return true

end

local funcs = {
scale = function(self, arg, uids) return self:SetScale(arg) end,
colour = function(self, arg, uids) return self:SetColor(arg) end,
name = function(self, arg, uids) return self:SetName(arg) end,
model = function(self, arg, uids) return self:SetModel(arg) end,
ang = function(self, arg, uids) return self:SetAngles(arg) end,
material = function(self, arg, uids) return self:SetMaterial(arg) end,
parent = function(self, arg, uids) self.parent = uids[arg] return self:SetParent(uids[arg]) end,
pos = function(self, arg, uids) return self:SetPos(arg) end,
uid = function(self, arg, uids) return true end, // dummy function
object = function(self, arg, uids) return true end, // dummy function
version = function(self, arg, uids) return true end, // dummy function
type = function(null, arg, uids) if arg == “ClipPlane” then return ClipPlane:New(nil)
elseif arg == “ModelContainer” then return ModelContainer:New(nil)
else return nil end end
}

local function addToRColl(rcoll, mdls, uids)

// initialize new objects, populate uid table
// this occurs first to allow easier handling of inter-object relationships
for k, prj in pairs(mdls) do
	if prj.uid == nil then ErrorNoHalt("Nil uid for passed PRJObject.  Abandoning load attempt.") return false end
	
	prj.object 			= funcs.type(nil, prj.type, uids)
	prj.object.parent	= rcoll		//TODO: eliminate
	uids[prj.uid]		= prj.object
end


local obj, success
// for each prjobject, get defined keyvalues and attempt to config the associated attribute in the newly created object
for _, prj in pairs(mdls) do
	obj = prj.object

	for k, v in pairs(prj) do
		if k != "type" then
			success = pcall(funcs[k], obj, v, uids)
			if !success then ErrorNoHalt("Invalid PRJObject keyvalue "..tostring(k).."	"..tostring(v).." for version "..PRJObject.Version.." loader.  Abandoning load attempt.") return false end
		end
	end
end

for _, prj in pairs(mdls) do
	rcoll:Add(prj.object)
	prj.object = nil
end

return true

end
[/lua]

Something I’ve noticed is, it’s alot easier to use pseudo-metatables than real metatables. I can post an example of my Hexadecimal library as an example :

[Lua]

– This script is under this license : https://sites.google.com/site/jamesaddons/home/terms-of-Service

// Stuff

local floor,insert = math.floor, table.insert
local function basen(n,b)

n = floor(n)
if not b or b == 10 then return tostring(n) end

local digits = "0123456789ABCDEF"
local t = {}

repeat
	local d = (n % b) + 1
	n = floor(n / b)
	insert(t, 1, digits:sub(d,d))
until n == 0

return table.concat(t,"")

end

// The hex

local HexTable = {

Data = "",

SetData = function( self , NewData ) self.Data = NewData end,
Len = function( self ) return #self.Data end,
CanGet = function( self, Length ) return ( self:Len( ) &gt; Length ) end,
GetData = function( self ) return self.Data end,
WriteRaw = function( self , Value ) self.Data = Value .. self.Data end,

GetPacket = function( self )
	local String = "";
	while( self:CanGet( 2 ) )do
		String = String .. string.char( self:GetInt( 2 ) )
	end
	return String
end,

GetPacketSize = function( self )
	return self:Len( ) / 2
end,

// Integers

GetInt = function( self , Length )
	if ( !self:CanGet( Length ) ) then return false end
	local String = string.sub( self:GetData( ) , 0 , Length );
	self.Data = string.gsub( self.Data , String , "" );
	return tonumber( String, 16 )
end,

WriteInt = function( self, Int , Length )
	local i = basen( Int , 16 )
	local ToAdd = Length - #i;
	if ( ToAdd &gt; 0 ) then i = string.rep( "0" , ToAdd ) .. i end
	self:WriteRaw( i );
end,

// Stream of Hexadecimal chars

GetStream = function( self, Length )
	if ( !self:CanGet( Length ) ) then return false end
	local String = string.sub( self:GetData( ) , 0 , Length );
	self.Data = string.gsub( self.Data , String , "" );
	return String
end,

WriteStream = function( self , Table )
	for i=#Table,1,-1 do
		self:WriteRaw( Table* , 2 )
	end
	return ( #Table * 2 )
end,


// Stream with no length

GetStreamNoLen = function( self, Termination )
	Termination = Termination or 0x00;
	local Save = ""
	while( self:CanGet( 2 ) ) do
		local MyInt = self:GetInt( 2 );
		if ( MyInt != Termination ) then
			break
		else
			Save = Save .. MyInt
		end
	end
	return  Save
end,

WriteStreamNoLen = function( self, Table, Termination )
	Termination = Termination or 0x00;
	local Length = self:WriteStream( Table )
	self:WriteInt( Termination, 2 );
	return ( Length + 2 )
end,

// String

GetString = function( self, Termination )
	Termination = Termination or 0x00;
	local Save = ""
	while( self:CanGet( 2 ) ) do
		local Int = self:GetInt( 2 )
		if ( Int == Termination ) then break end
		Save = Save .. string.char( Int )
	end
	return Save
end,

WriteString = function( self, String, Termination )
	Termination = Termination or 0;
	self:WriteInt( Termination, 0, 2 )
	for k,v in pairs( string.ToTable( string.reverse( String ) ) ) do
		self:WriteInt( string.byte( v ) , 2 );
	end
	return self
end

}

function Hex( Data )

local t = table.Copy( HexTable );
t.Data = Data or ""

return t

end
[/Lua]

I put all my functions in a local table, and when I need to use the functions, it returns a copy of that table.

Just saying.

That uses way more resources than real metatables, but sure that works too. I find myself using those too when I want to code something quick, but in the long run real metatables are better.