13

Previously I was searching for a good TimeLine control for a WPF project. I found an answer in Here which direct me to this CodePlex project.

Now I want to change code to feed my culture needs. But there are some mismatches!

My question is:

How you interact with such thousands lines of code?

EDIT:

Any shortcut will be great!

10
  • 3
    ask for a raise. it always helps. (they can make a motivator out of this) Nov 25, 2010 at 10:36
  • 2
    bang your head against the desk until it all becomes clear. Nov 25, 2010 at 21:49
  • 19
    How do you eat an elephant? ... One bite at a time.
    – Bill
    Mar 1, 2011 at 15:55
  • 1
    @Jalal That's what they want you to think. Mar 31, 2011 at 0:56
  • 2
    @DisplayName, the carrot and the stick approach to motivation has been shown to be a poor solution for any work that requires rudimentary cognitive skill. The science of motivation is more complex than the reward system. Check out 'Drive: The surprising truth about what motivates us' by Dan Pink, it is an astounding read. Or check out this you tube video for a condensed version. youtube.com/watch?v=u6XAPnuFjJc Mar 14, 2012 at 13:11

18 Answers 18

38

You add comments to the source code when you have understood it enough to be able to do so. Refactor these comments vigorously as you understand more and more.

3
  • 3
    +1 and one good way is to actually write the documentation as you browse the source code. And why to send your contribution back to the op coordinators?
    – user2567
    Nov 25, 2010 at 10:59
  • 1
    +1 Also, if you modify the code be sure that you change your comments as well, so that futuregenerations are not confused over what you did. Be a shame to do all that doc and have people hate it cause it's wrong!
    – Michael K
    Nov 25, 2010 at 18:39
  • 1
    If the original project is in a distributed source control system (like git) it would be beneficial to fork it, commit your changes incrementally and do it in a way so you can optionally merge your changes back later to the original
    – user1249
    Nov 26, 2010 at 10:10
8
  1. Step through the code
  2. Rename as needed
  3. Refactor as needed
  4. Repeat until you completely understand

... and the code will thank you for it. ;-)

4
  • 7
    Changing random places in production code just because it's easier, is not a very good idea. Only feature requests should cause code modification, re-factoring is a feature request. No matter how good you are, code breaks, sometimes stupid side effects is what customers rely upon. Refactor only code you're very sure of. And remember, even unit-tests don't guarantee anything.
    – Coder
    Mar 13, 2012 at 22:52
  • Agreed, but refactoring just to try out a design can help you understand why the code is written the way it is (or confirm that you're correct that it's done badly/oddly). You don't have to keep those changes. Mar 14, 2012 at 16:30
  • +1 Coder. And this answer currently doesn't even mention unit tests. Scary.
    – MarkJ
    Mar 14, 2012 at 17:10
  • Sorry, didn't mean major refactoring. Was talking more about minor refactoring, cleanup type stuff. So eventually, you get to the point that the purpose of the code is obvious. Mar 14, 2012 at 23:14
5

Take single action, debug (again and again) the code to find how that action is accomplished. Write down the same in simple language to get a better understanding!

3
  • I normally do this as well until I face a project which is not able to run in debug mode! It always crash during start up! :( But it runs fine in Release Mode :S Nov 25, 2010 at 23:12
  • @afriza WHAT THE FUCK. That's some seriously bad code, check what errors it gives you.
    – Daniel S
    Nov 26, 2010 at 15:07
  • @afriza, first thing to fix!
    – user1249
    Feb 7, 2011 at 15:30
4

Something that Joel Spolsky wrote way back when on his blog (can't find the article now) really stuck with me regarding this:

He said how code is not natural human language, but as programmers, we are easily lulled into thinking that it is, and that we should be able to read it as such. Consequently, a lot of us look at new code and expect to be able to just "read it" and understand it immediately, as if it was a block of text in English.

So I think the key is to basically just be slow, methodical, and scientific. And as others have said - comment it (and even refactor) as you go. Don't fall into the mindset of "I should just look at it and understand immediately".

Oh, and yes, I still fall into this trap myself sometimes. "Do as I say, not as I do", and all that. :)

2
  • Fact is, English text that you can "just read" is usually linear, the reason why code is often difficult to digest at first is generally because it is non-linear and the trick is just breaking it down. The plethora of different implementation idioms that developers use doesn't generally help either, but the first stage is usually running the code through a debugger, and using breakpoints to see what's what. Trying to just read it is a fairly pointless exercise. Seriously, when did you last just read code you've written? (start to end that is.)
    – ocodo
    Jan 5, 2011 at 8:07
  • Actually, well written code is easy to read, but not as a text. You just scan over to see the building blocks and understand the core structure, no need to read everything. Bad coding approaches, like old skool code, or abuse of SOLID and patterns can make this task very hard though.
    – Coder
    Mar 13, 2012 at 22:55
4

SE-Radio interviewed Dave Thomas about this very subject

This podcast episode has many tips and techniques to enter the 'culture' of the project and understand how the original inhabitants lived.

1
  • The hilarious part about Dave Thomas’s experience is that documentation — beyond a high-level overview — is (almost) without exception worse than no documentation at all. (In my experience it’s because most documentation is boilerplate giving a surface-level understanding of the “what” or “how,” which invariably is then left to become out of date, to the point of being misleading.) Mar 14, 2012 at 15:28
2

I had to do this recently with a project of over 100,000 LOC. My first idea was that it's easier to see patterns from graphs of 100 or even 1000 nodes than from 100,000 lines of text.

So I spent 45 minutes and wrote a short (<100LOC) Python program to parse what I needed from it, and draw the object relationships. I generated Graphviz source, which is a really easy language to generate. (There's nothing special about Python here: Ruby or C# or Common Lisp or whatever could do it just as well.)

On other projects, I've seen people use Graphviz for module dependencies, call graphs, version history, all kinds of things. Greatest program visualization meta-tool ever.

(Maybe it's because I took compilers, but I find it weird that when a programmer is faced with a problem, the answer seems to always be "write a program!", except when the problem involves the source code to a program. :-)

1

Step through it in the debugger as it runs, its nearly the only way to understand a new, large code base.

3
  • 2
    That's not a practical option when you have thousands of line of code (specially when we are talking of tens or hundred of KLOCs), and/or if part of that code is in templates. To get a grip on a new (and poorly documented) code base, one must also engage the business and try to understand the context in which the code is supposed to run. If you can go through the code with a debugger and get an understanding of it, that code base wasn't that large to begin with (making the use of a debugger rather unnecessary in most cases.) Feb 7, 2011 at 13:10
  • Woe betide if the code base is too large to debug in a debugger. Seeing the code react to a known input and output helps to transform the knowledge of "what" to "how". The question "why" is never one that can be answered with a debugger alone, but there may be inline source comments you can see in the IDE as you debug.
    – grrussel
    Feb 7, 2011 at 14:33
  • @grrussel I have to disagree because its not what I do... I've no idea whether I'm representative or not though! I can sort of see use the odd breakpoint (but still not explicitly stepping through) and I do use IDE features to allow me to relate one piece to another.
    – Murph
    Apr 9, 2012 at 15:00
1

Understand that there really are no shortcuts to grokking in fullness. (And if you have trouble with that phrase, your education has been SORELY neglected. It is from "Stranger In a Strange Land", by Robert A. Heinlein.)

Read it, one page at a time, one routine at a time. Add comments. Draw pictures of major data structures. Recognize algorithms. Draw upon previous knowledge.

Resist the temptation to crank up the debugger. The debugger viewport is too small: you see one line at a time, but you really don't see where you've been or where you're going.

2
  • The debugger explains some convention the original code writer's conventions about what are expected inside the variables (e.g. Do they expect Full-Path or filename or relative path?) and many other things so it is still important in my opinion Nov 25, 2010 at 23:15
  • 2
    -1 for thinking that you're cool because you use the word "grok" Apr 1, 2011 at 22:41
1

Whatever you do write up as much as you can as you go along so no-one ever ends up in the same position as you have.

1

you need to use clues. get a clue of what you have to look for and extensively use the search functionality of your environment or IDE that can bring you to the desired section of the code that you need to make change to.

reading 14 thousand lines of java code does not make any sense. Search functionality is your life saver

0

Different people have different learning styles, so YMMV. The first thing I do in this situation is read the entire code base through at least once. That gives me a general idea of where everything is. Then I choose a section to examine in more detail. Data structures would be a good place to start. Once I have a general idea of what's going on, I do the same with another portion of the code that interacts with the first. After enough iterations, I have a good sense of how the code works.

0

The best way, as with all programming not just large chunks of uncommented code, is to break it down into pieces. This is both something you should do in your head as well as visually in the code. This may mean adding big bold comments or multiple line breaks. This helps while scrolling through it to see the pieces. Try to find the logical chunks of code.

Of course, as you understand bits, comment them for what you know at that time, possibly putting in notes about about something you don't understand.

I would also recommend not trying to understand the entire piece right from the start. Instead try to understand the pieces that you need to know right now and work on the rest later.

0

I would start by using the Leo Editor in @shadow mode with active use of cloned nodes. This allows one to add notes and comments for each section of code under study without changing the code, and the annotations will always be in context, next to the code it's talking about. Here's an example workflow the docs:

For example, when I fix a bug in Leo, I create an ordinary node to represent the bug. This bug node is my view of all the data in Leo’s source code that relates to the bug. As I discover code related to the bug, I clone their nodes and move them under the bug node. I’ll also add ordinary nodes as children of the bug node. These nodes contain the original bug report, descriptions of how I fixed the bug, test data, or any other notes I might want to keep.

Once I have created the bug node, I concentrate only on that node and its children. I can examine the bug node and its children without having to jump around the outline. Everything I need is in one place. When I get around to actually fixing the bug I can do so by changing the clones. Again, I do not have to jump around the outline. It doesn’t matter how big or complex the entire outline is: I am only dealing with the bug node and its children. This extremely narrow focus makes it much easier to fix bugs.

0

Draw diagrams of the source: the data relationships, the functional relationships, the object relationships. Determine aggregation, data flow, and code flow. Pictures are far better than comments for this, and can be kept separate from the code.

0

Before you refactor anything write tests. Lots of tests. Very specific tests to small blocks of code that are at least callable, as it'll depend on how your inherited mess is written.

The advantage to writing tests to begin with is that you need to have some kind of understanding of the code before you can test it, so every test you write will hopefully be a little bit of knowledge gained. You can also heavily comment the tests with your assumptions alongside the assertions.

By doing it test first, you don't run the risk of altering something in the code that has knock-on effects you can't know about. You'll also have a safety net when you do come to refactor the code.

0

I use tools like doxygen, to generate an overall class diagram, than adds my understanding of what each of the classes do.

Then I pick up some easy bug from the bug queue (before my manager assign a hard one to me :P), then run through that functionality into debugger and try to generate a rough data flow or code flow model.

For example export functionality in some software: so I try to understand how the source data is read, from where in the code (base interface) can I evaluate the data is read correctly using my class and code flow diagrams, which classes are responsible for which type of exports, etc. I think half of the understanding is done, once you have the class diagrams and flow charts.

0

Approach a trivial defect, e.g., a NullPointerException. Avoid anything regarding concurrency at first, anything that by its nature will involve understanding a lot of the code at once.

Once you've fixed a few bugs you'll probably have a pretty good idea. Works for me, at any rate.

-2

Basically the action to write a clean code should start right from design. If we are coding in OOP language come up with a UML ,share with peers and get convinced that design is not ambigous . In any case we developers should get convinced that design solves the problem and not ambiguos.

When it comes to coding we have to make sure the design is getting converted to code i.e. an Entity to a class or struct , an operation to function etc.

And i went through a white paper http://queue.acm.org/detail.cfm?id=2063168 which talks about coding style or how we can use space, indentation , Font variation as most IDEs do we can use to write MUCH CLEANER code where we humans can understand as much as machines do. It stresses more on writing comment free code so that our code will appear as paragraphs itself.

Not the answer you're looking for? Browse other questions tagged or ask your own question.