I'm shocked - and indeed appalled - at the number of answers here saying "don't update unless you have to". I've done that, and whilst it's easier in the short term, it burns like hell in the long run. More frequent, smaller updates are much, much easier to manage than occasional big ones, and you get the benefit of new features, bug fixes, and so on sooner.
I don't buy this idea that library changes are somehow more difficult to test than code changes. It's just the same - you're making a change to the codebase, and you need to validate it before you commit, and more deeply before you release. But you must already have processes to do this, since you're making code changes!
If you're working in iterations, of two to four weeks length, i would suggest making updating libraries a once per iteration task, to be done as soon as possible after the start, when things are a little more relaxed than just before an iteration deadline, and the project has more capacity to absorb change. Get someone (or a pair if you do pair programming) to sit down, look at which libraries have been updated, and try bringing each one in and running a rebuild and test. Budget half a day to a day for it each iteration, perhaps. If things work, check in the changes (i'm assuming you keep libraries in source control, as we do; i'm not sure how you'd propagate the change in a controlled way if not). This will obviously be a lot easier if you have automated tests than if testing is entirely manual.
Now, the question is what you do if an update breaks things - do you spend time fixing it, or leave it out? I'd suggest leaning towards the latter; if it can be fixed in an hour, do it, but if an update is going to take significant work to integrate, then raise it as its own development task, to be estimated, prioritised, and scheduled just like any other. The chances are that unless it brings in some very crucial fix or improvement, the priority will be low, and you'll never get round to it. But you never know, by the time the next iterationly update day rolls round, the problem might have fixed itself; even if not, at least now you know that there's a roadblock on the update path, and it won't catch you by surprise.
If you're not doing iterations of that length, i would set up some kind of standalone schedule for updates - no longer than monthly. Is there some other project rhythm you could tie it to, like a monthly status review, or an architecture board meeting? Payday? Pizza night? Full moon? Whatever, you need to find something a lot shorter than a traditional release cycle, because trying to update everything in one go every 6-18 months is going to be painful and demoralising.
Needless to say, if you do stabilisation branches before releases, you wouldn't apply this policy to them. There, you'd only update libraries to get critical fixes.
This is always a trade-off.
As a beginning programmer, you should ask yourself two questions when considering reusing code vs. reinventing the square wheel:
- Will I learn more about the problem I want to solve by writing everything from scratch, or by focusing on the problem domain and putting aside complexity not critical to the problem that I am interested in?
- Is it more important to me to solve the problem at hand or is it more important that I understand some fundamental concepts?
If you don't have to finish your project, it's fine to spin your wheels on complex problems that other people have already solved, because you'll learn something. But you'll probably move on to something else before you "finish," which may or may not matter to you. Other projects will start to look shiny fast when you get in over your head on a complex domain that looks simple until you start trying to solve it yourself.
Don't obsess about giving up control because you're deferring to someone else's way of thinking; focus more on what you're trying to accomplish.
If your goal is to write an HTML parser because you want to understand how parsers work, go for it. If your goal is to write an HTML parser because you want to sanitize user input or transform some random bits of HTML, you're probably focused on the wrong thing, because you probably are more interested in the application of parsing rather than the parsing itself.
If you feel like writing an HTML parser because you don't want to take time to understand someone else's library, you're probably wasting your time, because, at least in this case, I guarantee someone else has spent more time figuring out how to solve this problem effectively than you'll have. In really trivial cases, you may save time by not reusing code, but in complex ones, unless the library you use sucks or your ability to read documentation and code samples sucks, you'll just waste time.
On the other hand, I would say that it's worth writing your own graph library, since you'll be more focused on transferable, fundamental algorithms and data structures that you'll be able to apply to other domains, even if you end up using someone else's library when you work on those problems.
Best Answer
If you only use a small subset of the third party API, it makes sense to write a wrapper - this helps with encapsulation and information hiding, ensuring you don't expose a possibly huge API to your own code. It can also help with making sure that any functionality you don't want to use is "hidden".
Another good reason for a wrapper is if you expect to change the third party library. If this is a piece of infrastructure you know you will not change, do not write a wrapper for it.