Commenting

正在查看此主题的用户

Commenting is a pain for me. I know I should comment my scripts, but I'm not entirely sure how often and where to do it. I'm always wondering if I'm doing it enough and correctly. Does anyone have some guidelines for commenting code? I don't think that it's likely that there are any rules, but I would like to know if what I do is enough to prevent headaches when I look at the scripts in the future.
 
Comments should be used when doing anything out of the ordinary.  For example, without the comment here, I might not have learned how to end a for loop prematurely:

(try_for_range,":new_village",villages_begin, villages_end),
(try_begin),
(party_slot_eq,":new_village",slot_village_bound_center,0),  ##make sure it is not used!
(party_relocate_near_party,":new_village","p_main_party"),
(enable_party,":new_village"),
(display_message, "@You have founded a new village!"),
(assign,":founded",1),
(assign,":new_village",0),  ##Break loop
(try_end),
(try_end),

Ok, this is my code block, but you get the point.  You can also see above I mark out why I am testing the value.  This block is actually pretty sparse for my commenting.  If you had to figure out how a part of your code works, or the reasons are not totally clear, then comment.  Another smart commenting idea is to label (such as in scripts) at the beginning of the script, the global (including strings and regs) variables that you will be using.  This will make it easier for those that look at your code to know if there may be variable conflicts.  You wouldn't want a block of code to alter, say, reg5 if you are holding a value in there.

The only bad thing about over commenting is that it can look messy, especially if you are having someone else trouble shoot your code.
 
I guess it's a matter of preference. I have a ****ty memory so I tend to comment quite a lot.

At the very least I comment what each block does.. so in this script I'm working on:

插入代码块:
	#schedule maintenance and send them out
	(else_try),
		(get_party_ai_current_behavior,":cur_behavior",":cur_patrol"),
		(eq,":cur_behavior",ai_bhvr_in_town),
		(eq,":cur_object", ":cur_home_base"), #make sure it's not in the wrong town
		(assign, reg22, ":cur_object"),
#		(display_message,"@ship is at home base, scheduling maintenance"),
		(call_script, "script_patrol_unit_maintenance", ":cur_patrol"),
		(party_set_ai_behavior, ":cur_patrol", ai_bhvr_patrol_party), #send them on their way again.
		(party_set_ai_object, ":cur_patrol", ":cur_home_base"),
#		(display_message, "@sent patrol out after rendezvous"), #test

	#in case they somehow ended up in the wrong town
	(else_try),
		(get_party_ai_current_behavior,":cur_behavior",":cur_patrol"),
		(eq,":cur_behavior",ai_bhvr_in_town),
		(neq,":cur_object", ":cur_home_base"), #they're in the wrong town, send em home
		(party_set_ai_behavior, ":cur_patrol", ai_bhvr_travel_to_party),
		(party_set_ai_object, ":cur_patrol", ":cur_home_base"),	
	(try_end),
	]),

Using notepad++ you're able to set different colors for all the different parts of the code so it's still easy to read.

I also tend to comment on parts when I'm play testing (#this works, #this needs to be changed to scipt_x, etc)
And then I comment on anything that's not immediately obvious when reading the code, usually only the first time I use it in the first block of a script/trigger, etc.

And I put a description before each trigger or script, same as native does with the scripts.. so the name, input, output and general use of it. That's mostly for other people if they ever have to modify it.

Since python skips empty lines anyway, I try to set it up clearly, separating blocks with an empty line, etc. Makes it so much easier when you're trying to fix something that's not working, you can quickly see where you're at, etc.
 
Both jik and MartinF make excellent points.

I would add that most code is grossly under-commented.  Commenting every line is retarded, clearly not a useful practice.  But there should be a title block for each logical unit of code (trigger, script, dialog-block, etc.) giving it a quick-summary of what it does, what arguments it takes, and what output it produces.  Good examples of this can be seen in the scripts module, which has excellent title blocks.

But similar to MartinF, the code itself should be commented for what its doing.  The main advantage to this is that someone scanning over your code can *just* read the comments and get a quick skeletal understanding of the code's basic logical blocks and what its attempting to do.

However, the bigger benefit of commenting logical blocks is:

  • so that when things aren't working right, you can easily see what your intention is and whether it matches up to what the code *actually* does
  • jog your own memory when you come back to this code later to enhance it
  • its easy to search for and reuse code that does things that you want someplace else
  • other programmers can easily learn from your code and extend the ideas (or reuse them elsewhere, etc.)

I know from my own personal experience that I used to be confused as to how much or little to comment.  And I heard folks speaking of it as though it was a chore.

I think if its a chore to you - then you're doing it wrong.  Its primary function in my life as a programmer is to HELP ME.  I love being able to scan over my own code blocks and know at a glance wtf I was doing, and where I was going with something.  The mental effort required to parse C++ or Python or even batch scripts is 1000x harder than that required to read a few lines of English.  So I save myself literally hours (years at this point) of my own time by not forcing myself to have to parse the code as though I were a computer, and instead treated myself humanely, as a human being.  And, of course for any other programmers having the joy of being stuck with maintaining my code in the future, I've helped them as well, which can only be a good thing (Lord knows I've seen enough poorly written and convoluted code that only an author could love that I've had to slog through before I could do anything to fix or improve on it in any way).

One of the ways I comment is as a first step when trying to use / fix / extend another's piece of code: I comment it as I go in order to comprehend its function and that  author's intentions.  That way, the structure of the code is usually more apparent, and now the comments are available to anyone else who has to decode this chunk.

Cheers!
 
I think what Mordachai says also applies to other basic stuff like picking variable names, slot names, etc. I always try to pick something that describes what I actually use the thing for so when I have to go back later, I can figure it out more easily.

And really it should just be common sense. Like he says, we're not computers and our brains don't work the same ways, but sometimes we have to think like one to figure out what's working (or more usually, not working) how. So just try to make that as easy for yourself as you can.

Another thing I've recently started doing is put a try_end down as soon as I type try_begin. Even with notepad++'s ability to close try blocks so you can see where they start and end (it recognizes else_try as well) it can still be really difficult to figure out the flow in long blocks. And again, using empty lines can make things much easier to follow at a glance.

If you haven't already, get it for sure, it has other great features such as highlighting a block that's similar to your selection, so you can see straight away if you've misspelled a variable name by accident and the advanced search functions, such as searching through all the files in the module folder for a certain script or global variable can make figuring out the native code much easier. 
 
Yes - always immediately adding the matching end-of-block for any given programming language is a must for "top 10 practices of successful programmers".

Along those lines, INDENTATION is a must.  Every nested conditional block should be indented one layer relative to the rest, so that at a glance, which code refers to which conditions should be obvious, and matching up begin/end blocks should be obvious.

In Python, that means (try_begin) should have the same indentation that its corresponding (else_try)'s and (try_end)'s have, and that code within each of those chunks should be one level deeper indented.

插入代码块:
(try_begin),
  (some_code),
(else_try),
  (some_other_code),
(try_end),
 
后退
顶部 底部