ID:266051
 
So BYOND, how do you lay out your programming? What little things do you do, that make you happy when programming.

Mine little quirks are:
-I use a folder system, 'Icons', 'Programming'-'A-M','N-Z'
-I generally have one system per programming file
-Ontop of that I generally make my programming incredibly modular, believing in the great power of reusing code
-I leave an example of how to use my programming at the top of the file
-I don't always comment, but when I do, I find myself being hilarious
-I like to keep procs simple, generally having a 'master' proc that will do a long string of procs in a row. Again for modularity


Small example of programming that I just did:

/*
mob/verb/Make_Name(var/T as text)
var/message = ewnh_checkName(T)
if(message == 0)
ewnh_characterNames += T
world<<"Name added to registry!"
else
world<<"[message]"
*/

var
list
ewnh_characterNames = new/list()
ewnh_disallowedCharacters = list("<",">","/","\\",{"
"}
)
ewnh_disallowedWords = list("tallywhacker","bottom")

proc
ewnh_checkName(var/name)
if(!name)return "No Name"
if(ewnh_checkLongName(name))return "Name Too Long"
if(ewnh_checkDisallowedCharacter(name))return "Disallowed Character"
if(ewnh_checkDisallowedWord(name))return "Profain Langauge"
if(ewnh_checkDuplicateName(name))return "Name Already In Use"
return 0



Since my stuff is so descriptive (I like to think), I don't have the need to comment as much. Obviously I haven't included the actual procs in this, but do I really need to? You should be able to tell what each one does exactly.

Edit:
Oh incase you're wondering what all the ewnh_ stuff is, it's so that everything's very specific to that file. I can reuse variable names, for example I might have a disallowedWords variable within a spam filter, so that would be ewsf_disallowedWords.

Some might argue this is a bad way of handling it and I should just reuse the same variables (What are the chances of me allowing certain words in names but not the spam filter?) but I say phooey to you!

-Wookie
It looks well organized, though I'm not too sure about the prefixes:

1. You have to remember that "ewsf" means "spam filter". This isn't a problem when you're in the spam filter file looking at tons of vars and procs that have the ewsf- prefix, but when you're in another file trying to refer to spam filter functionality it won't be as clear.

2. Trying to define the disallowedWords var twice (once for the spam filter and once for character naming) could mean that the variable names need to be more specific or that both systems should use the same var.

I'd also change the proc names. By looking at the code I can tell that ewnh_checkLongName returns true if the name is too long, but from the proc name alone you wouldn't know that. If it was called ewnh_isNameTooLong it'd be more obvious. It's one less thing you have to remember.

I don't always comment, but when I do, I find myself being hilarious

I'm not sure what that means exactly but I don't write a lot of comments either. I only comment heavily when it's code that other people might be reading. The Sidescroller library has ~5800 lines in .dm files but ~1300 are comments (21%). Tiny Heroes has ~7000 lines but ~670 are comments (9%). Both have about the same amount of whitespace (20% for SS, 18% for TH).

Ontop of that I generally make my programming incredibly modular, believing in the great power of reusing code

Being modular doesn't just help because you can reuse code

It also helps because you can change how the code works without needing to change all code that references it. In your example you can easily change how ewnh_checkName() works and you don't need to change how it's called.

It also helps to limit how much you need to remember to use the code elsewhere. Suppose you wrote ewnh_checkName like this instead:

proc
ewnh_checkName(name, maxLength, list/disallowedCharacters, list/disallowedWords, list/existingNames)
if(!name)return "No Name"
if(ewnh_checkLongName(name, maxLength))return "Name Too Long"
if(ewnh_checkDisallowedCharacter(name, disallowedCharacters))return "Disallowed Character"
if(ewnh_checkDisallowedWord(name, disallowedWords))return "Profain Langauge"
if(ewnh_checkDuplicateName(name, existingNames))return "Name Already In Use"
return 0


Because you wrote it as a self-contained module, you just have a proc that takes a name and returns an indication of whether or not it's an acceptable name. It's very easy to use. If you had done things this way, you'd need to remember all of those arguments and it'd be a hassle to use this proc elsewhere - you'd probably have to flip back and forth between .dm files to double check the order of the arguments every time you wanted to call it.
In response to Forum_account
1. You have to remember that "ewsf" means "spam filter". This isn't a problem when you're in the spam filter file looking at tons of vars and procs that have the ewsf- prefix, but when you're in another file trying to refer to spam filter functionality it won't be as clear.

This is a very valid point, however the idea is that I should never need to refer the functionality, it should all just work off a single (Or a few) procs. I'd think to myself:

'Hm, so now I'm creating a new character, I need to make sure that the name is valid.'
-I would then quickly check the list of dm files for a relevent one, in this case- nameHandling.dm, and from that derive what my prefix should be- ewnh_.

The variables and functions contained within nameHandling.dm should ideally never be used outside of it, completely arguing against my reusing code system =P


I'm not sure what that means exactly but I don't write a lot of comments either.

Since I attempt to program in such a way that I wouldn't need comments personally, when I do write comments they're aimed at other people reading them. For example, in another project of mine I have the following:

                                                step_towards(src,M)
//Boots are made for walkin etc.



My comments are aimed less towards helping refer what the programming means, more towards making it bearable for the reader.
In response to El Wookie
El Wookie wrote:
The variables and functions contained within nameHandling.dm should ideally never be used outside of it, completely arguing against my reusing code system =P

Exactly =)

I suppose you could do it like this:

// contents of name-handling.dm:

proc
// this is the one you call from other files
checkName(n)
return ewnh_checkName(n)

// these are internal to this file, so they get the prefix
ewnh_checkName(n)
ewnh_checkLongName(n)
ewnh_checkDisallowedCharacter(n)
ewnh_checkDisallowedWord(n)
ewnh_checkDuplicateName(n)


That way you know that the procs with prefixes can be a little messy because they're all in the same file. If you have to look up how one of them works, it's right there. Also, if you find yourself wanting to call one of them from another file that'll be an indication that name-handling.dm needs another global proc to expose those ewnh- procs.

It's like defining public and private procs. You can make any changes to the ewnh- procs as long as checkName(), the one that'll be called from other files, doesn't change.

Since I attempt to program in such a way that I wouldn't need comments personally, when I do write comments they're aimed at other people reading them. For example, in another project of mine I have the following:

>                                               step_towards(src,M)
> //Boots are made for walkin etc.
>

My comments are aimed less towards helping refer what the programming means, more towards making it bearable for the reader.

There's nothing wrong with keeping it fun =)
In response to Forum_account
I suppose you could do it like this:

But this method again causes another issue, whilst I know it's pretty obvious in this case, what happens when I have a proc such as <code>colourHandling()</code> for adding user-defined colours to their text (for a more varied <code>Say()</code> verb or such like). What happens when it comes to modifying this proc, for example, after two weeks of not looking at the programming files at all. I'm sure I'd forget where I put it. Whereas if I had <code>ewth_colourHandling()</code>, I'd instantly know it's within my textHandling.dm file.

I know both ways have their for and against reasons, but I like to think my way is winning so far >;)
In response to El Wookie
The prefix actually sounds pretty handy, but for safety's sake I would keep a prefix-definitions.dm file, where I list out what each prefix stands for and where it is created.
In response to Albro1
That is a very neat idea!
In response to El Wookie
El Wookie wrote:
I suppose you could do it like this:

But this method again causes another issue, whilst I know it's pretty obvious in this case, what happens when I have a proc such as <code>colourHandling()</code> for adding user-defined colours to their text (for a more varied <code>Say()</code> verb or such like). What happens when it comes to modifying this proc, for example, after two weeks of not looking at the programming files at all. I'm sure I'd forget where I put it. Whereas if I had <code>ewth_colourHandling()</code>, I'd instantly know it's within my textHandling.dm file.

My way you'd have to remember where the proc is when you want to edit it*, your way you'd have to remember where it is and what the prefix is when you want to use it. Having to remember the prefix is the part I don't like because you can't guarantee that you'll have descriptive prefixes. If you know that the colourHandling() proc is part of text handling, you have the full filename (textHandling.dm) to describe its contents. The two character prefix th- isn't as descriptive, so even if you know that the color handling proc is part of your text handling functions, it might not be obvious that the prefix is ewth- (especially if there's another feature that'd be abbreviated as "th").

* Though you can use ctrl+F or the "Objects" tab to find it.

I know both ways have their for and against reasons, but I like to think my way is winning so far >;)

Fair enough =)

How you program is always a balance between a good way of doing things and your own style/preferences.

Edit:
Your method is just a different balance. Each balance has its pros and cons. Yours has pros that you appreciate (but I don't) and cons that you tolerate (but I wouldn't). What's important is that you're aware of what the pros and cons are and realize that you can do things different when it'll be beneficial to do so. You seem to be aware of this so it's fine. It bothers me to see DM developers writing code a certain way because it looks cool or seems neat, even though it's clearly bad.
In response to Albro1
Then you have to traverse a file to figure out what the prefix means/where it's stored, then another to get to it. It'd be easier if the file name reflected the prefix (but then, you may as well start grouping like files, and etc etc).

Traversing files is something you should do as little as possible (it wastes a lot of time), especially since the vanilla IDE has no support for multiple files being open).
In response to DivineTraveller
Traversing files takes a lot of time? You must have one hell of a slow mouse speed...
In response to Albro1
Or you could drop the "ew" in front of everything, and use longer abbreviations: "name_checkName", "spam_disallowedWords", etc...