Hello again to all of my readers. I am traveling to Montréal tomorrow and then I'll be back in the states in time for Thanksgiving. I'll be back online to add posts to my blog after that. I know you all will miss me very much, anxious to get updates to this feed. But just hold tight, have a very Thankful Thanksgiving, and I'll see you in the wintertime.
Sometimes, a project can take a lot of work to get loaded onto your computer. There might be some pre-requisite libraries to install, some database creation and migration scripts to run, and other low-level setup that probably has to be done in a certain order to boot.
Luckily, as programmers, we can write shell scripts for our projects that others can use to set the project up easily. And of course they come in handy for ourselves when we find we're copying the project onto another workstation for whatever reason.
It's really quite trivial to write such a script. I keep mine in the bin/ folder as bin/setup. Others keep them in the script/ folder, but it really doesn't matter so long as you document it correctly in your README.
Here's a gist of one of my bin/setup files:
As you can see, it's pretty simple and only works on a system that supports homebrew, which I believe is only OS X. It could be modified, however, to check for other OS' and run different code. It's just shell script.
To make the file work, you'll have to set execute permissions on it like so:
$ chmod +x bin/setup
Then instruct your readers how to use it in a README:
It is quite handy to have such scripts in each of your projects. Even if the setup is simple and straightforward, it's great for the practice and to get into the habit of making them. It helps your work stand out, too, as others will appreciate you taking the time to make their work a little easier.
I'm on the road! Well, I was on the road. Now I'm in LA. I've been visiting friends and relaxing, taking time off in between contracts and job hunting. I'll be meeting a client in Orange County to demo their project that I recently finished, but other than that I'm not here on business.
I drove 2,400 miles here, visited a friend in Prescott, Arizona, and picked up hitchhikers who were from Montréal (a couple of blocks from my old apartment as it turns out). I hiked the Will Rogers State Historic Park the other day, and we're going up to the miracle tree and the hollywood sign tomorrow.
This coming weekend, I'll be going to San Francisco for a few days, hoping to meet up with friends there, and then heading back along the northern highways to Chicago. I'm staying there for a week-long interview and audition. After I return from Chicago, I've got plans to fly to Montréal to see my old roommate for his birthday. It's going to be quite a month!
Here are some photos from the trip:
I know that sounds strange, but bear with me. Software should absolutely do what your client paid for it to do, otherwise you won't stay in business for very long. But that is not the primary value of a working piece of software. The primary value of software is its ability to change.
This isn't an original idea on my part, it comes from Uncle Bob, a renowned veteran programmer who has lots of great advice for coding professionals. I don't mean to appeal to authority so much as give credit for the idea so that I may expound upon it without false pretenses. Not everyone likes Uncle Bob's advice, and maybe it's not for everyone. That's okay. It works out quite well for me. What follows is his idea, from my experience, in my own words.
The primary value of software is its ability to change. What do we mean when we adopt this premise? The fact is, as long as software is in use, someone will ask for changes to it. Long after the estimated budget is spent and the contract has been fulfilled, someone using your software will want it to change. We want to be able to make quick and easy changes, because that will take less time and cost less money. Developers will also be happier and more relaxed as they work in the code; they won't be fighting deadlines and constantly sweating it out for two hours past closing time.
This is why we practice clean coding, test-driven development, and refactoring the code's design. We strive to make the system easier to understand, and for its design to pop right out to other developers. Remember that 'other developers' includes ourselves three months after we last touched the code. To help other developers and ourselves in the future, it should just make sense where things fit and how things work. Well written unit tests, paired with carefully crafted production code, help us keep our systems simple, loosely coupled, and easy to change.
Making software easier to change takes diligence and discipline, and at first this seems like it adds time and too much effort. Maybe that is true early on when you're first trying things out. But it is worth all the extra effort and any homework you can do to practice it, and it does become second nature. It doesn't take long for it to kick in, either. Once you know how to recognize things, you recognize them quickly and often.
We can learn techniques that give us the ability to spot coding problems early on. Developers call this 'code smells.' We look for issues, or sniff out smells, such as duplicated knowledge, poorly named variables, functions that are too long, complex function signatures, awkward object instantiation procedures, and more.
An easy way to build momentum with diligence is to follow the Red, Green, Refactor TDD cycle. Start with a failing test (RED), write just enough production code to pass the test (GREEN), and then refactor (REFACTOR). We look for the smells early and often, and therefore we clean them up early and often. That way, we're always doing the refactors when refactoring is a small task, and not a large, daunting undertaking. Of course, big refactors will come along once a larger design emerges, but they will be easier to make because most things will fit and fall into place.
Another technique that works for me is to push my code to Github and proofread it there. Github is a great "read-only" editor for code. "Read-only" in quotes because you can edit files there, but for the most part you're just browsing the structure of the files and the code. About three or four times, I go over the components and tests that I have recently written. I slowly scroll up and down each file, making sure that what I wrote is sensible and easy to follow, and giving it the squint test. You literally squint your eyes and see if the shape and spacing of the code is elegant. I also review the tests to see if setting up and using the objects is simple and straight-forward, and doesn't expose too much internal knowledge.
Those are just a few ideas and techniques for keeping an eye on your code's ability to change. Software design is a subjective practice with some well-crafted general patterns and solutions for achieving conventional results. Maybe you have some of your own that work for you, and you should definitely write about them and share them. I certainly hope this has been helpful to anyone out there, and I hope it has shed some light on the mysteries of software craftsmanship.
Tmux is a great tool for development and for pairing, whether in-office or remote. Hell, the remote tools are just as useful when you're sitting next to each other. Okay, what is tmux? At its most basic level, it's a great way to stay on the keyboard while managing different windows and panes of editors, consoles, and other commandline utilities in one shared terminal session. An editor here, a server there, continuous integration, a console, and a shell. Sometimes in tab-like windows, sometimes in the same window in their own panes, right there with your text editor and console. Think of it like a jsfiddle screen.
Tmux makes it easy to use all my windows with a well of keyboard shortcuts, avoiding mouse use. You might think mouse use is no big deal, that it's a trivial bit of effort and time, but hey that does add up, and staying on the keyboard helps me keep my focus. The shortcuts give you great power at your fingertips, though, and fingertip speed trumps wrist, arm, and hand to mouse, back to keyboard speed. Personally, I enjoy development at fingertip speed and tmux has a pretty low barrier to entry on learning.
Setting up tmux is painless if you have homebrew installed.
Just use brew install tmux.
Pretty much every command is prefixed with the, well, prefix command, which is Ctrl+b. You can configure that. Mine is set to Ctrl+a, for example. From there you can open new windows, open new panes, switch your focus between windows and panes, rename them, detach sessions, close sessions, and more.
In the tmux book, they recommend creating a bash script for your various tmux workstations. Here's one of mine. I just saved it to a file named 'jamby' in my home directory, I run ./jamby in terminal from my home directory, and my workstation is ready to go.
It sets up the first window for vim, the second window for the rails server (it runs git pull, bundle, and rake db:migrate on the current branch), and the third window left on the commandline prompt named git.
Has this ever happened to you? I know I'm still guilty of it from time to time. You're looking for a solution to your problem online, and you find a blog post or Stack Overflow solution that looks like it's got the answer. Then you scroll straight to the code examples, and you copy and paste it into your project. You refresh the browser and tweak and fiddle with what you pasted until it works. Sometimes, it just doesn't work and you don't understand why. 'What the hell? They said this code fixes my problem!' What went wrong?
You didn't read the blog post. You skipped the explanation. It turns out that the piece of code you copied requires some sort of prerequisite setting, or only applies in a given situation that is similar to the one you're having, but does not apply here. They provided a link to another solution, but you missed it. In a hurry to "just get it done," you've glossed over the information that could potentially teach you what you need to know about the nature of the problem. You've missed an opportunity to know better for next time.
Be more interested in the nature of your problem than the solution to it. This will make you a better developer. You'll recognize similar problems in the future and you'll have at least half an understanding of what to do when things go wrong again. When you find a potential solution to your problem, slow down and read everything on the page about it. A slower developer is a faster developer. A developer who takes the time to understand and to do a job well is a developer who has more time to get more things done.
I like to say, the developer who takes the time, has the time.
How is it that a slower developer is faster, and a developer who takes more time to research a problem will have more time to finish their tasks? You might be thinking that that makes no sense. A slower developer is faster and has more time for more tasks because they now understand more about what they're doing, and can act faster in the long-term. The developer who took the time to do the job well is not constantly putting out fires from the tasks they thought they had already completed. The educated programmer avoids common pitfalls and mistakes that keep others stuck playing whack-a-mole on the same tasks over and over again.
If you find a tutorial or documentation about how to integrate a third party service into your application, read the whole thing first without touching your code editor. If you want, feel free to play around in a console, but don't copy and paste a single line of the samples into your production code. Instead, get yourself familiar with the problem domain and how to use the service to suit the needs of your system. Once you feel like you have 40% of the information you need, start writing tests, and then write your own production code. The code in the tutorial isn't your code. It's an example. Your code should reflect the needs of your system.
Next time you're tempted to 'just get it done,' and copy and paste the samples, challenge yourself to stop, go slow, and write your own code.