The Pragmatic Programmer: Your Journey to Mastery, 20th Anniversary Edition
Rate it:
Open Preview
73%
Flag icon
Tests can definitely help drive development. But, as with every drive, unless you have a destination in mind, you can end up going in circles.
73%
Flag icon
We like to think of unit testing as testing against contract (see Topic 23, ​Design by Contract​). We want to write test cases that ensure that a given unit honors its contract.
74%
Flag icon
Suppose we have a module A that uses a DataFeed and a LinearRegression. In order, we would test: DataFeed’s contract, in full LinearRegression’s contract, in full A’s contract, which relies on the other contracts but does not directly expose them This style of testing requires you to test subcomponents of a module first. Once the subcomponents have been verified, then the module itself can be tested.
74%
Flag icon
But that ignores the fact that tests are also a way of communicating with other developers, so I now do write tests on code shared with others or that relies on the peculiarities of external dependencies. Andy says I shouldn’t include this sidebar. He worries it will tempt inexperienced developers not to test. Here’s my compromise:
Alexander Bandukwala
What about regression
79%
Flag icon
In the first edition’s discussion of code coupling we made a bold and naive statement: “we don’t need to be as paranoid as spies or dissidents.” We were wrong. In fact, you do need to be that paranoid, every day.
79%
Flag icon
Minimize Attack Surface Area Principle of Least Privilege Secure Defaults Encrypt Sensitive Data Maintain Security Updates
79%
Flag icon
Never trust data from an external entity, always sanitize it before passing it on to a database, view rendering, or other processing.
79%
Flag icon
Some languages can help with this. In Ruby, for example, variables holding external input are tainted, which limits what operations can be performed on them.
Alexander Bandukwala
Fascinating. Read later
80%
Flag icon
Principle of Least Privilege Another key principle is to use the least amount of privilege for the shortest time you can get away with.
80%
Flag icon
Every program and every privileged user of the system should operate using the least amount of privilege necessary to complete the job.— Jerome Saltzer, Communications of the ACM, 1974.
81%
Flag icon
We believe that things should be named according to the role they play in your code.
81%
Flag icon
Most people we ask would call it fib. Seems reasonable, but remember it will normally be called in the context of its module, so the call would be Fib.fib(n). How about calling it of or nth instead:
81%
Flag icon
There’s a well-established tradition that projects and project teams should have obscure, “clever” names. Names of Pokémon, Marvel superheroes, cute mammals, Lord of the Rings characters, you name it.
Alexander Bandukwala
Thanks, i hate it.
81%
Flag icon
Most introductory computer texts will admonish you never to use single letter variables such as i, j, or k.[69] We think they’re wrong. Sort of.
82%
Flag icon
Some languages allow a subset of Unicode in names. Get a sense of what the community expects before going all cute with names like ɹǝsn or εξέρχεται.
82%
Flag icon
Make renaming easy, and do it often.
83%
Flag icon
Perfection is achieved, not when there is nothing left to add but when there is nothing left to take away...
84%
Flag icon
Implement the general case, with the policy information as an example of the type of thing the system needs to support.
84%
Flag icon
This example also illustrates our belief that successful tools adapt to the hands that use them.
84%
Flag icon
Create and maintain a project glossary—one place that defines all the specific terms and vocabulary used in a project. All participants in the project, from end users to support staff, should use the glossary to ensure consistency. This implies that the glossary needs to be widely accessible—a good argument for online documentation.
84%
Flag icon
It’s hard to succeed on a project if users and developers call the same thing by different names or, even worse, refer to different things by the same name.
85%
Flag icon
The popular buzz-phrase “thinking outside the box” encourages us to recognize constraints that might not be applicable and to ignore them. But this phrase isn’t entirely accurate. If the “box” is the boundary of constraints and conditions, then the trick is to find the box, which may be considerably larger than you think.
85%
Flag icon
Andy wrote an entire book about this kind of thing: Pragmatic Thinking and Learning: Refactor Your Wetware [Hun08]
86%
Flag icon
I’ve never met a human being who would want to read 17,000 pages of documentation, and if there was, I’d kill him to get him out of the gene pool. Joseph Costello, President of Cadence
86%
Flag icon
How do Committees Invent? [Con68]
86%
Flag icon
Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.
86%
Flag icon
But most importantly, development teams that include users will produce software that clearly reflects that involvement, and teams that don’t bother will reflect that, too.
87%
Flag icon
In fact, whenever someone says “do this, and you’ll be agile,” they are wrong. By definition.
87%
Flag icon
The manifesto suggests that you do this by gathering and acting on feedback. So here’s our recipe for working in an agile way: 1. Work out where you are. 2. Make the smallest meaningful step towards where you want to be. 3. Evaluate where you end up, and fix anything you broke.
89%
Flag icon
Build teams so you can build code end-to-end, incrementally and iteratively.
89%
Flag icon
A great way to ensure both consistency and accuracy is to automate everything the team does. Why struggle with code formatting standards when your editor or IDE can do it for you automatically? Why do manual testing when the continuous build can run tests automatically? Why deploy by hand when automation can do it the same way every time, repeatably and reliably?
89%
Flag icon
Read The Mythical Man Month [Bro96] by Frederick Brooks. For extra credit, buy two copies so you can read it twice as fast.
91%
Flag icon
If a bug slips through the net of existing tests, you need to add a new test to trap it next time.
92%
Flag icon
How will you know that we’ve all been successful a month (or a year, or whatever) after this project is done?
99%
Flag icon
In the second chunk of code, each step returns an object that implements the next function we call: the object returned by content_of must implement find_matching_lines, and so on. This means that the object returned by content_of is coupled to our code. Imagine the requirement changed, and we have to ignore lines starting with a # character. In the transformation style, that would be easy:
1 2 4 Next »