Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm 2 weeks into learning Objective-C (but previous experience with Java and Python), and after the initial hurdle I'm starting to get a hang of things like pointers, ARC, and delegates. However, on more than one occasion I've come across a problem/bug that I have no idea how to solve, and worse, I have no idea how to approach a solution.
My general troubleshooting strategy, for when things aren't working as expected, is as follows:
Reread through the relevant section of my code to make sure the general logic and flow makes sense
Look at any self-defined methods and make sure they're working properly
Put a few NSLog statements within the code to see where it is doing unexpected things
Once I've identified the troublesome part(s), search the apple docs/stackoverflow/google to see if anyone has experienced the same problems.
I might be omitting a step , but this general process works for the most part. However, there are some problems that I come across for which this process does not work, and I get totally stuck. A few examples:
I was trying to load an NSWindowController using the proper method called in the proper location, but it wasn't displaying. Turned out to be an issue with pointers, after a long time of aimless experimenting
I'm testing an example pulled directly from an Apple Technical Q&A to create a clickable hyperlink into an NSAttributedString, but when you hover over said link the pointing hand cursor does not appear. See my thread for more info.
I've created an NSButton and want the pointing hand cursor to appear when I hover over the button. I'm using the code in the accepted answer here, but it doesn't work and I don't know why. Also, subclassing every button I want to use would be tedious and messy.
Clearly my troubleshooting strategy is not working. Once I exhaust all 4 steps to no avail, I have to just try random fixes until one, seemingly magically, works. This is neither time efficient nor good for helping me understand the language better. Are there steps that I can add to my troubleshooting strategy, and if so, what are they?
For example, when I asked a friend the same question, they suggested using breakpoints to monitor instance variables and objects.
When you get across a bug,
first thing you need to do is read the error, see what the error is and where it occurred.
Go to that specific location of the error, see if there is an obvious mistake.
If not, set up a break point at skeptical location, then step in and check step by step to see if each value on the stack is what you expected it to be.
You may want to put up some test, consider all possibilities, such as what if this value is null, what if it's 0, etc.
Sometimes bugs are tricky, but is not really recommended to read your code all over again each time you see an error.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Randomly ran across this blog on how one should never read comments, and thought to myself all the comments I've read that were either wrong, dated, or simply confusing. Should one simple never read comments and/or just use regex replace pattern to delete... :-) ...just kidding, but really, maybe not. At the very least seems like comments and the related code should be have timestamps. Agree, or no?
FYI, blog appears to be by this stackoverflow user: Nosredna
An inaccurate comment is just as serious of a bug as wrong code. If it is a persistent problem, I would say the project has serious issues. Big projects such as PostgreSQL (94M uncompressed in src directory) rely on accurate comments to help programmers understand things quickly. They also take comments very seriously.
edit:
Also, if you can not summarize what your function is doing, then who can? After you are done writing a function, writing the comment for it can be a test that you fully understand what is going on. If things are still a little muddy in your mind, it will become very apparent when you try write the comment. And this a good thing, that shows what still needs to be worked on.
In the real world, programming does not just mean writing code. It means writing code that another programmer (or yourself, in 3 months time) can understand and maintain efficiently.
Any programmer who tells you that comments/documentation are not worth the time it takes to write/maintain them has a number of problems:
His long term work rate (and that of any colleagues who have to work with his code) will be lower than it could be. People will waste a lot of time understanding code that could be described in a quick sentence.
Bug rates relating to his code will be higher than they could be, because all those assumptions and special cases that he forgot to mention will constantly trip people up. (How many times have you had to do something "unusual" in your code to make something work, forgotten to comment it to say why you did it that way, and then later on thought it looked like a bug and "fixed" it, only to find that you've broken things horribly because of a subtlety you didn't remember?)
If he is too lazy to write down how his code works or should be used, what other shortcuts is he taking? Does he bother to check for nulls and handle exceptions? Does he care about his interfaces being consistent? Will he bother to refactor the name of a method/variable if its underlying meaning changes? Usually bad commenting is just the tip of the iceberg.
Many such programmers are too focussed on "the cool stuff" (like optimising every last cycle out of their code, or finding a clever way to obfuscate a seemingly simple piece of code into a mindboggling template) to understand commercial realities (e.g. he may have trouble getting his code working and shipped to deadlines because he focusses on squeezing unnecessary performance out of it rather than just getting the job done)
How good are his designs? I do most of my design and thinking when I write down docs/comments. By trying to explain things to the reader of my comments, I flush out a lot of flaws and assumptions that I otherwise would miss. I would go so far as to say that I usually write comments (my intent/design) and then sync the code with them. In most cases if there is a bug in my code, it is the code that is wrong not the comment.
He has not realised that by using good variable naming, well designed naming prefixes/conventions, and documentation comments, he can make much better use of fabulous time-saving features of his IDE (auto-complete, intellisense help, etc), and code much faster, with lower defect rates.
Fundamentally, he probably doesn't understand how to write good comments:
1) Comments should act as a quick-read summary of a chunk of code. I can read one brief line of text instead of having to work out the meaning of many lines of code. If you find yourself reading the code to navigate it, it is poorly commented. I read the comments to navigate and understand the code, and I only read the code itself when I actually need to work on that specific bit of it.
2) Method/Class comments should describe to a caller everything they need to know to use that class, without having to look inside the "black box" of the code implementation. They will be able to quickly grasp how to use the class/method, and understand all the side effects and the "contract" that an API provides - what can be null and what must be supplied, and which exceptions will be thrown, etc. If you have to read the code to get this, it's either badly encapsulated or badly documented.
3) Use tools like my AtomineerUtils addin or Submain's GhostDoc, which mean that his documentation comments can be kept in sync with the code with very little effort.
Code comments can sometimes be invaluable. Many times I've struggled to determine the intent of code unsuccessfully. For code of any complexity, it can be helpful if the author documents their intent. Of course, well written unit tests can make intent clear as well.
Personally I don't write a whole lot of comments, but common types of comments I do write are:
(sketch) proofs that my code is correct
explanations why not to just do the obvious thing (e.g: optimization was required, the API I'm calling is shockingly misleading, the "obvious thing" led to a subtle bug)
a description of the input edge-case which necessitates special handling, thus explaining why the special handling code appears
a reference to the requirement or specification which mandates the behaviour implemented by a particular line of code
top-level description of a series of steps taken: ("first get the input", "now strip the wrapper", "finally parse it"), which aren't needed if the names of the functions called for each step are well-chosen and unambiguous in context, but I'm not going to write a do-nothing wrapper for a generic function just to give it a more specific name for one single use
documentation to be extracted automatically. This is a large proportion of comments by volume, but I'm not sure it "really counts".
things that could be part of the documented interface, but aren't because they might need to change in future, or because they're internal helper stuff that outsiders don't need. Hence, useful for the implementer to be aware of, but not for the user. Private class invariants are included in this - do you really want to read through the whole class every time you want to rely on "this member is non-null", or "size is no greater than capacity", or "access to this member must be synchronized"? Better to check the description of the member before assigning to it, to see whether you're allowed to. If someone doesn't have the discipline to avoid breaking a clearly commented invariant, well, no wonder all their comments are wrong...
Some of those things are handled by comprehensive tests, in the sense that if the tests pass then the code is correct (hah), if you have the test code open too then you can see the special input cases, and if some fool hides the comments, makes the same mistake I originally did, and refactors my code to do the obvious thing, then the tests will fail. That doesn't mean comments don't handle it better, in the context of reading through code. In none of these cases is reading the comment a substitute for reading the code, they're designed to highlight what's important but not obvious.
Of course in the case of auto-docs, it's perfectly reasonable, and probably more usable, to view the documentation separately.
When debugging, as opposed to making changes, it's way more valuable to let the code explain itself. Comments are less useful, especially those private invariants, because if you're debugging then there's a reasonable chance that whoever wrote the code+comments made a mistake, so the comments may well be wrong. On the plus side, if you see a comment that doesn't reflect what the code does, there's a reasonable chance you've found a bug. If you just see what the code does, it might be some time before you realise that what the code does isn't what it's supposed to do.
Sometimes good naming goes a long way towards replacing comments. However, names can be just as misleading as comments if they're wrong. And, let's be honest, frequently names are at least slightly misleading or ambiguous. I doubt that the author of that blog post would go to the extent of replacing all names with "var1, var2, func1, func2, class1, class2 ...", just to make sure that they weren't distracted by the original author's incorrect intentions for the code. And I don't think it's any truer to say that "comments are always wrong" than to say that "variable names are always wrong". They're written by the same person at the same time with the same purpose.
Some comments are useful and good, other comments are not.
Yes, comments and code should be timestamped, but you shouldn't timestamp it yourself. Your source control system should manage this for you, and you should be able to access this information (e.g. using cvs annotate or svn blame).
Comment why you are doing something and not what you did syntactically.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
I've been wanting to help out with an open source project for some time now. I want to do this for two main reasons. I am a strong supporter of foss and I want to gain experience.
I've struggled to find a project that I thought I would want to help with. There are many I would like to help with, but they are far to complex for what I would want to start with. However, I recently found a browser, uzbl, which seems like it is complex enough for me to be able to learn from, however simple enough for me to be able to wrap my head around.
It is a simple lightweight browser which uses webkit and gtk.
Now that you are familiar with my positon, here is my question.
What is the best way to go about understanding the code base?
Now I realize this is a subjective question. However, I feel if I have the suggestions of more experienced developers, I may be able to cut down on the wrong turns I make.
Should I familiarize myself with the libraries used first? Or should I look through the core code and concern myself with what goes in under the hood after I have a basic understanding of the global picture?
How do you guys go about understanding the code base of a new project?
Thank you for your time and effort.
First, compile and run it. With many projects, simply accomplishing that task will give you some understanding :-)
Second, it's good to have some problem to solve. Some small task, like fix a minor bug somewhere. Just debug, search for the bug origin, try to fix it. Then run unit tests (if any), see what else you broke with your fix. Investigate that, too.
Then repeat. A dozen of bugs, preferably in different areas, give some better understanding of the codebase.
After that, I usually start wondering around the product, just looking how it works and playing with it. Natural curiosity takes over sooner or later, and I find a feature that interests me. In a "wow, I wonder how it works" kind of way. Then I try to sketch a high-level design for that feature myself. Along the lines of "what would I do if I had to create this feature? Very briefly, just in my mind, no fancy diagrams and whatnot.
In doing so, I inevitably find myself in need to know more about the system: after all, you can't design a fully isolated feature, can you? You'll have to interact with the rest of the system, and you need to know how. So I go into code and find out.
Then, a moment may come when I realize that I really don't know how to design this little part of that feature. I think, and I think, and I think, and I just don't know. So then comes the sweetest part: I go into the code and look how is it designed in the first place. Sometimes I would be disappointed in the project. But more often, I would be disappointed in myself. But that's exactly what's precious: that's how I learn.
I have found two things (in addition to the answer by Fyodor Soikin) that really help. One is getting doxygen to do document everything for me. It makes it a lot easier when I can go through the function declarations, and click the data structure which is supposed to be passed in so I can see all the members it contains (if there is no current documentation you can just set EXTRACT_ALL = YES). I also find it very useful to compile the project with debuggin symbols then run it in gdb so that you can follow it from start to finish.
I would look for their tests first, and look at those. If there aren't tests, I probably wouldn't bother with the project. If there are tests, they should be instructive as to how the software works. Step through the tests in the debugger to understand how the high level components fit together.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 13 years ago.
Improve this question
We've all been there. You have written some code and unit tests, the tests all pass, and the code is decent (nothing's perfect, right?). Then, someone who is sure that they know better than you comes along and decides to change your code or the interfaces to your code just because he/she does not like the variable/class names that you used. No "real" refactorings, no real optimizations, no real improvement -- just different words -- not necessarily better words, just different.
My real problem with this is that (a) its a waste of time and (b) it shows a blatant disrespect for the fellow developer that wrote the code in the first place.
My visceral response is to lash out, but that's counter productive. Instead, I though that I might wright a paragraph or two as sort of a "Charter" or "Philosophy" that is adopted for the project. I'm wondering if anyone else has tried this, and if so, was it successful?
After looking at the initial comments below (which are appreciated), I think that my problem is primarily that this change broke the build for code that was already working. So time needed to be spent to fix the code for what was (in my opinion) a non value-added change.
-- Thanks
...decides to change your code or the
interfaces to your code just because
he/she does not like the
variable/class names that you used.
My real problem with this is that (a)
its a waste of time and (b) it shows a
blatant disrespect for the fellow
developer that wrote the code in the
first place.
My visceral response is to lash out...
I see some VERY CONCERNING things in those statements.
naming is REALLY, REALLY important. It is worth rewriting code to get it correct.
It is not YOUR code
How is it disrespectful?
You are taking it too personally.
I once worked with someone who freaked out when I made changes to "his" code. His code as horrible; it was buggy and unmaintainable. He was always staying late, fighting fires and breaking things - basically a negative contributor. I rewrote all his bad code for a big piece of functionality for a project one weekend and when he came back in on monday had a hissy fit. I am not saying your stuff is horrible, but maybe you need to calm down and be more objective about it.
Don't take it so personally. Step back and think about it - maybe "your" code needed fixing
We might be able to give better answers if you posted the code and changes, or at least some better idea of the situation with an example or two.
EDIT:
After seeing the code change and finding out that the build was broken, I am going to have to change the tone of this answer. I understand Steve's frustration - and i agree - that is not a good change. It makes a specific typedef more general and not very descriptive any more.
While I think some of my points are valid, in this case it looks like the changes were not appropriate.
The issue of code "ownership" is irrelevant. If the code changes are useless then everyone on the team should not be happy. If they are good changes then everyone should be happy about it. If there is a difference of opinion then you all need to find a common ground.
Breaking the build is not a good thing.
Steve, sorry if I came down harsh - it looks like in this instance you are justified in your frustration, but not because it is "your" code.
One thing that might help in this sort of situation is to require code reviews for all changes. People are less likely to make pointless changes if someone else has to review it first. If they can actually convince another developer that their change should go in then maybe it isn't so pointless after all.
Heey,
Guys! WE all need TO TALK!
Just sit together and TALK! There are always reasons to change and there are always reasons NOT to.
Decide together!
Don't just go to StackOverflow or a forum and say ask this kind of questions.
The new dev does it - he gets responses from community probably positive (yeahh, bad code should be refactored).
The current dev does it - he gets responses from the community too: "What an idiot could do such kind of changes!"
And the result is: Counterproductive, destructive, offensive environment for a long time.
Who wants it?
Just put your arguments on the table and that's it.
New dev needs some introduction too.
Old dev needs to listed TOO.
This should be collaborative work AND not pissing each other off.
Decide together, talk, as THE TEAM.
And... better ask questions like "How is it better to refactor this?"
Cheers.
In any software development team with a size > 1, standardization is key. Not only for each developer to understand the other's code, but so that the people that come along in 2 years, 5 years and 10 years can look at any part of the code and see a clear and consistent pattern. Will you... and the rest of the team... seriously still be there, working on this project, years down the line?
If you both "just have your way of doing things" and there is no formal standard for the project/company, I suggest you work with the team and/or your boss to suggest a formal standard be adopted. There are many standards already published for the various environments that you can use either as the standard, or as a starting point.
If there is a formal standard, everyone on the team is obligated to follow it... no matter how much "better" they think their way is.
So much for the hard skills.
Now on the soft skills side...
You and your colleague need to develop a healthy relationship, or decide to work in different places. Tit-for-tats that result in people feeling that they want to lash out will make everyone unhappy, not to mention gravely jeopardize the project everyone is being paid to complete. Look for a person you both respect (maybe your boss, maybe a respected and level-headed senior member of the team, maybe HR if you have a good HR department). Explain to that person what the problem is and that it makes you feel unvalued and disrespected. Ask for help talking through the situation with your colleague and agreeing to a better way of working together.
Finally, you need to be open to the possibility that your colleague may be making subjectively correct changes, even if the manner he's doing it in offends you. Separate the correct coding from the correct interpersonal interactions. Do the right thing for the project.
Well if that guy is going to maintain your code, let him do whatever he wants to.
Just remember that it is not "your" code. The code belongs to the company for which you work for. You wrote the code and you got paid for it. Let the Management do whatever they want to do with it.
Don't take things personally, move on.
Sometimes, changing names might be justified. It can be confusing if half the project refers to a person's sex, and then you check in some new code that refers to gender or something. Okay, this might be a bad example as technically they are two different things and their meaning is most likely still obvious. But if a project's code uses two different terms to refer to the same concept, it can be confusing.
Usually I try to leave people's code alone, unless I have some justification for refactoring. Luckily the same seems to go for my colleagues, so no, I have not had the need for writing such a charter yet.
How about using an automated build system, so when this person changes the code and breaks something the team will get an alert about it. This solves your problem with having to waste your time fixing something broken by someone elses change to your code. This way everyone will know that so and so made a change and broke the build, and can see for themself. The rule is "dont break the build".
You should be discussing this with the person who did it, in a non-threatening manner.
I believe every developer should take responsibility and hence own some of the code, but not all of the code. I understand the code that I've written better (irrespective of how good/bad it is) than any other guy that has ever seen it. Therefore the changes I make will be faster and less prone to error.
I don't mind anybody changing the code I've written later on, but I have a couple of conditions:
If you change the code and that causes something else to break, you are responsible for fixing it, not me.
If I don't agree with the changes you made I will change it back to the way I want it since I have to take responsibility for this piece of code in future.
Not all developers should be making changes to all the code, all the time. Only some of the time, for the purpose of getting to know the code (sharing knowledge).
I've never worked for an employer that endorses a "everyone can change anything any time" policy. Developers own certain parts of the code and they are asked specifically to make changes/refactor based on a development democracy.
You touch my code and break something, (1) you better have a good reason for the change that all developers agree with and (2) you better not leave broken things broken or ask me to go do the clean-up for you UNLESS you're my superior. I will humbly submit if that's the case.
I agree with Laurence that code reviews might help. This is an issue of how your team should work together. What might help is the notion of Egoless Programming - in a nutshell, considering the code as a joint product of the team, and trying to make decisions for the sake of the code rather than because of the programmer's ego. Your teammate violated the fourth commandment of egoless programming - "Don't rewrite code without consultation."
Maybe if your team is made aware of these principles, things will improve. I would try this.
Perhaps not completely on topic, but .... If you have developers who have the time to make changes to code just because they don't like the variable names used, then maybe the conversation should be about whether you have too many developers and which ones should be shown the door ... or how you're going to justify to management the bloated staff you have, especially in the current economic circumstances!
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
We have a project hand over from on shore team to our team (off shore) not long ago. However we were having difficulties for the hand-over process.
We couldn't think of any questions to ask during their design walk-through, because we were overwhelmed by the sheer amount of information. We wanted to ask, but we didn't know what to ask. Since they got no question from us, the management think that the hand-over process was been done successfully.
We had tried to go through all the documentation from our company wiki page before attending the handover presentation, but there are too many documents, we don't even know where to start with.
I wonder, are there any rules or best practices that we can follow, to ensure a successful project hand-over, either from us, or to us.
Thanks.
In terms of reading the documentation, personally I'd go for this order:
Get a short overview of the basic function of the application - what is it meant to achieve. The business case is probably the best document which will already exist.
Then the functional specification. At this point you're not trying to understand any sort of how or technology, just what the app is meant to do. If it's massive, ask them what they key business processes are and focus on those.
Then the high level technical overview. This should include an architecture diagram, required platforms, versions, config and so on. List any questions you have.
Then skim any other useful looking technical documents - certainly a FAQ if there is one, test scripts can be good too as they outline detailed "how to" type scenarios. Maybe it's just me but I find reading technical documents before I've seen the system a waste - it's too academic and they're normally shockingly written. It's certainly an area I'd limit the time I spent on if I didn't feel I was getting a reasonable return for the time I was spending.
If there are several of you arrage structured reviews between you and discuss the documents you've read, making sure you've got what you need to out of it. If the system is big then each take an area and present to the others on it - give yourselves a reason to learn as much as possible and knowing you're going to be quizzed is a good motivator. Make a list of questions where you don't understand something. Having structured reviews between you will focus your minds and make it more of an interactive task, rather than just trawling through page after page of tedious document.
Once you get face to face with them:
Start with a full system demo. Ask questions as they come up, don't let them fob you off with unclear answers - if they can't answer something have it written down and task them with getting the answer.
Now get the code checked out and running on your machines. Do this on at least two machines - one they lead, one you lead. Document the whole process - this is the most important step. If you can't get the code running you're screwed.
Go through the build process. Ensure that you can build the app (including any automated build and unit tests they may have). Note that all unit tests should pass - if they don't or if they say "oh, that one always fails" then they need to fix that before final acceptance.
Go through the install process. Do this at least twice, one they lead, once you lead. Make sure that it's documented.
Now come up with a set of common business functions carried out with the application. Use this to walk the code with them. The code base will be too big to cover the whole thing but make sure you cover a representative sample.
If there is a database or an API do a similar exercise. Come up with some standard data you might need to extract or some basic tasks you might need to carry out using the API and spend some time working through these with them.
Ask them if there's anything they think you should know.
Make sure that any questions you've written down anywhere else are answered.
You may consider it worth going through the bug list (open and closed) - start with the high priority ones and talk through anything particularly worrying looking. Even if they've fixed it it may point at a bit of code which is troublesome.
And finally if the opportunity exists - if there are any outstanding bugs or changes, see if you can pair program a couple.
Do not finally accept the app unless you are 100% sure you can:
Get the code to compile
Get the code to build (including the database)
Get the application installed
Do not accept handover is complete until they have:
Documented anything you picked up on that wasn't covered to your satisfaction
Answered ALL of your questions - a question they won't answer after being asked repeatedly screams of something they're hiding
And grab their e-mail addresses and phone numbers. Even if it's only informal they'll probably be willing to help out if the shit really hits the fan...
Good luck.
My basic process for receiving a handover would be:
Get a general overview of the app, document it
Get a list of all future work that the client expects
... all known issues
... any implementation specifics
As much up-to-date documentation they have
If possible, have them write some tests for critical components of the system (or at least get them thoroughly documented)
If there is too much documentation (possible) just confirm that it is all up to date, and make sure you find out from them where to start, if it is not clear.
Ask as many question as possible; anything that comes to mind, because you may not have the chance again.
Most handovers, perhaps all of them, will cause a lot of information to be lost. The only effective way to perform a handover that I have seen is to do it gradually. One way to do it is to allow a few key people from phase One to stay on the project well into Phase Two.
The extreme solution is to get rid of all handovers, and start using an Agile mindset.
As a start, define the exit criteria for the handover. This should be discussed, negotiated and agreed with both parties and make sure higher management knows this. Then write up a checklist of all things needed to achieve the exit criteria and chase it.
Check out "Software Requirements" and Software Requirement Patterns for ideas on questions to ask when gathering information about a project. I think that just as they would work for new development, they would also help you to come to terms with an existing project.