I was working in Java yesterday to parse a URL that had a somewhat flexible format, so I set up my unit tests, wrote the code in a declarative fashion using
substring(), and got to greenbar. Then I looked at the code and shuddered at its inelegance. Time to switch to regular expressions.
Just in case someone hasn’t heard the Jamie Zawinski quote on regular expressions:
Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
(further discussion on quote and its source: http://regex.info/blog/2006-09-15/247)
I spent the next 30 minutes or so writing and debugging a regular expression to do what my declarative code did. When I finally got it right, I tweeted:
Pattern.compile(".+/(.[^/\\.]+).*")got me to greenbar. #regex
Almost immediately, my older brother Ben (@BenWarner) DM’ed me:
Worst. Status. Update. EVAR!!11!!!
Despite being a quoted Twitter expert (http://www.usatoday.com/tech/news/2010-05-25-1Atwitter25_CV_N.htm), Ben doesn’t know a regular expression from prune juice, nor does he know the feeling of victory at getting a regular expression to work. I stand by my status!
Sadly, however, my regular expression had a bug: an extra period. I had to add some more tests to catch it. Here’s the final solution:
The company I work for, Availity, LLC, provides (among other things) a web application that allows healthcare providers to submit transactions to insurance companies and get responses, all in real time. Users learn just one user interface (ours), submit the transaction to us, and we do the dirty work of routing the transaction to the insurance company, receiving the response, validating it according to HIPAA guidelines, and displaying the response back to the user.
One of the transactions that providers can submit through us is called an Eligibility and Benefits Inquiry, which determines whether the patient is indeed covered by insurance, what their copay is, what their deductible is and how close they are to meeting it, and what other benefits they have. Traditionally, providers have called the insurance companies to gather this information, but through our portal they get this information faster, more accurately, and more completely. When a patient walks up, providers can type the patients’ information into our screen or swipe their insurance card through a card reader, and presto! The Eligibility and Benefits information appears, and the providers know how much money to collect up front from the patients.
I told you all that to tell you this. Last Saturday, we were releasing new software (“we” meaning Availity — I wasn’t involved with this release). We haven’t yet moved to an active-active datacenter scenario, so when we release software we typically notify the users that we’ll be performing system maintenance, we take down the systems, upgrade them, run our tests, and bring the systems back up. While the systems are down, any attempts to hit our login page show a generic, “Sorry, we’re performing system maintenance” screen. Our release for last Saturday was scheduled to run 9:00 AM – noon (we usually perform upgrades on Saturday nights — I’m not sure why this one happened Saturday morning), so the notice that went out to users said we’d be down on Saturday from 9:00 AM – noon. On Friday, though, I saw an email that they decided to start the upgrade at 7:00 AM so they could have the web application up by 8:00 AM (the upgrade involved other systems as well).
Saturday morning, I went to a clinic to get my elbow X-rayed — I’ve had intermittent pain since I banged it against the floor in a basketball game a month ago, and it’s very sensitive to the touch. When I went to the reception desk to settle up, they said Availity was down. It was about 9:00 AM, so I was surprised that the web portion was still unavailable. I tried bringing up the Availity application on my iPhone, and the login screen appeared. This meant that the web application was up and running, so I tried logging in, and that worked, too. I explained to the person at the front desk that Availity wasn’t down and showed her my iPhone as proof. The eavesdropper working next to her said Availity was down from 9:00 AM to noon for system maintenance. I explained that I worked for Availity, and that the maintenance (as far as they were concerned) was complete, and they could use the Availity services to pull my Eligibility and Benefits information. The person helping me tried to log in, and the system told her that the password she’d entered was incorrect. She said, “See? Availity is down!”
I was part of the project that replaced the security system that went to Production about a month ago (two days before I hurt my elbow, in fact), so I’m particularly sensitive to login issues. I explained that Availity wasn’t down, that the fact that it could tell her that her password was wrong was evidence that Availity was running, and that she obviously had mistyped her password. She tried again, got the same error message, and said, “See? It’s down!”
During this exchange, the eavesdropper kept bleating, “Availity is down today from 9:00 to noon!” I’m shocked and a little grateful that she’d read and memorized the notice, but here I was not only superseding the message, but also promising to make her morning less difficult. I tried again to tell the person helping me that she evidently had the wrong password, and that she should use the sleek, wonderful “I forgot my password” function to reset her password and get into the system. She kept insisting that her password was right and that Availity was down.
My need to win arguments has fallen dramatically over my life (whether from age, marriage, or parenthood), so I smiled, told them my deductible was met (which it is — one of the benefits of having five children) and I have no copay (which I don’t) and they let me go. I’m not sure how well they coped with the rest of their morning without running any Eligibility and Benefits Inquiries, and I wonder if the one woman ever got her password reset or if she’ll keep typing in the wrong one until the system locks her out. Most of all, though, I wonder: Why don’t users listen?
When Michael Privat (@michaelprivat) and I signed up to write a book for Apress, we both gulped at the schedule: one chapter due each week. He gulped because, despite being a book virgin, it sounded like a breakneck pace. I gulped as a book veteran because I remembered the work involved in bringing The Definitive Guide to SWT and JFace to press. Writing this book seemed like a good opportunity, though, so we steeled our fingers, set our brains, and started working. We just finished drafting chapter five, and we’re precisely on schedule: five chapters, five weeks. Four chapters and four weeks to go!
Here’s what I’ve learned so far:
I only halfway jest. We both have full-time jobs at Availity, LLC. Michael is the technical lead on the game-changing platform rewrite of our core-business application that has regulatory implications with the new 5010 mandate, so he has dates to hit and a schedule to keep. I’ve transitioned out of management to a new role we’re calling Senior Technical Staff Member, so I’m scouring off five years of management rust and trying to justify my existence by developing solutions in Objective-C, Rails, Java, and Grails. We both have families (Michael has two children and I have five) that want us to succeed but won’t let us disappear while we write. Little children can’t walk to soccer games or hip-hop lessons. Something has to give in our schedules, and that thing is usually sleep.
When I saw a mini-fridge on sale for $58 at Walmart, I bought one and slipped it under my desk at work. It stays well-stocked with Coke Zero, Diet Dr. Pepper, and Pepsi Max. I’ve worn a trail in the carpet between my desk and the bathroom, but the caffeine usually keeps me awake. I don’t know what Michael’s secret is, as he works from home four days a week, but his emails and checkins evidence that he’s not sleeping much, either.
Work with Someone Brilliant
On the same principle that you should have a workout partner to ensure you exercise, having someone else you’re accountable to for delivery helps you work through the times you want to defer tasks. Knowing someone is counting on you to complete your work provides motivation.
Also, having someone working with you means you don’t have to do everything. More workers means more work done.
Working with someone brilliant — and Michael is that — helps you elevate your own game. It also means that you have someone to unstick you when you get stuck, who provides different perspectives, who gives you someone to bounce ideas off, and who gives you an opportunity to play critic when they bounce their ideas off you.
I couldn’t write this book, especially at this pace, by myself.
Use the Right Tools
Writing: MacVim and TextMate
We knew when we started this project that we didn’t want to write in Microsoft Word — whatever its strengths and weaknesses, its output is binary, and we wanted something we could easily diff. We also knew we’d be working on different sections simultaneously within the same chapter, so we wanted to break the sections of each chapter into separate files. Michael is a LaTeX guru, which I’ve used enough to know that with Google I can use it to format anything. We know Apress has published some books from sources in LaTeX and Markdown (see, for example, Pro Git), so we explained our desires to our project manager, who patiently explained that our schedule can’t accommodate the scripts and challenges of fitting LaTeX and Markdown files into something that Apress can publish, so we had to use Word.
Undaunted, we emailed Dave Mark (@davemark), who has authored and co-authored more books than you may have read in your life, including iOS books for Apress, and asked him how he solved this dilemma. He confessed that they knuckled under and just used Word, though he had other pieces of advice we readily accepted.
We settled on writing everything in plain text using text editors. I use MacVim and Michael uses TextMate. We can edit each other’s files easily and diff any changes. We have sections broken out into different files, so we can work on different sections without worrying about collisions. An example file tree for a chapter is:
ch01 +-->00-Intro +-->Intro.txt +-->01-WhatIsCoreData +-->WhatIsCoreData.txt
Any screenshots or other graphics files go into the appropriate section’s directory. Code goes into a Sources directory, either inside the section’s directory for code specific to a section, or inside the chapter’s directory for code that applies to more than one section.
When we’re ready to submit a chapter, we create the Word document, paste in the text, and apply formatting. The pbcopy tool comes in handy here —
pbcopy < 00-Intro/Intro.txt copies the content of
00-Intro/Intro.txt to the clipboard, for example, ready for pasting into Word. While we’re writing and reviewing, we aren’t distracted by formatting or styles — in a text editor, all we can do is write.
Coding and Diagramming
We write all code in Xcode 4 and create all diagrams in OmniGraffle. Xcode 4 is in pre-release, but it will likely be available by the time the book comes out so we don’t want the book to look dated. Besides, using Xcode 4’s new features usually outweighs the instability of a pre-release version.
I’ve long believed that if it ain’t in source control, it doesn’t exist. Everything we do is in source control. We use Git, with a private repository on Beanstalk to share changes. We commit words and code several times a day, and we always have the correct versions of files.
As I mentioned above, although Michael and I live in the same city and work for the same company, we don’t see each other all that often. Michael works from home four days a week, and when we’re at work we have other things to do. We touch base at work occasionally, but our real communication happens elsewhere:
- Project Management in FogBugz. Each chapter has a task, and each section within a chapter is a subtask of that chapter. We assign the sections, and have defined states: Draft, Review, Passed Peer Review, and Complete. We always know who’s working on what and what state it’s in.
- Time-sensitive communication via SMS or IM. We both have Macs, iPhones, and BeejiveIM. When we have to communicate something or get an answer right now, we text or IM.
- Email for less time-sensitive communication. Our email threads can grow pretty long, but we both make sure to check often enough that no questions goes unanswered for more than a few hours.
- Occasional face-to-face meetings. Whether meeting for lunch during a workday or meeting at Barnes & Noble on a night or weekend, we try to meet face-to-face every week or two to recalibrate our bearings. I’ve found it essential to both understand and be understood on what we’re doing and what the next steps are.
Lose Your Fear
We miss so many opportunities to do things because we’re too afraid to finish them. As we write, we push ourselves to move forward and write. Editing comes later, and we have a team to help us. Our first sentences won’t be our best sentences, but that’s OK. Keep writing, keep moving forward, and refine as you go. But make sure to go.
We crossed the halfway point today, at least for writing, when we finished the draft of chapter five. The book has nine chapters, so we still have a lot to do. With the right partner, the right tools, and my stocked mini-fridge, I know we’re going to make it. And in case you were wondering, that’s a dragon fruit on the cover!
Every so often I search Amazon for Pro Core Data for iOS, which I did this morning. Last time I checked, we didn’t have a cover image, but now we do! Look here.
I have no idea what that is, either, so I’ve asked our project manager to enlighten us. Any guesses?
We’re also working to update the “About the Author” section to include Michael.
We’re finishing up Chapter 5 this weekend. I’m writing about the undo manager right now.
After some discussion with Apress, I’ve decided to move my blog from there to here. Many thanks to Apress for hosting my blog all these years. We must still like each other, too, because not only do I fill my shelves and my nook with all kinds of Apress titles, but I’m finally writing a second book for them. Details to come soon.
Many thanks to Pete Aylward at Apress for helping me move my content from there to here. We had an adventure, as the version of WordPress running Ablog didn’t have an export feature. Pete exported my entries as a CSV, and I converted them to a WXR (WordPress eXport Record, if memory serves) and imported them. I had some trouble finding a WXR spec, until I realized I had WordPress running and able to export entries, so I created a couple of dummy entries (yeah, yeah, I know — ALL of my entries are dummy entries) and exported them to a WXR file. From there, I was able to reverse engineer the format, write a Ruby program to convert the data, and I was good to go. As you look at past entries, you’ll find them out of order chronologically, so I put an original post date on them and was satisfied. You’ll also find some formatting glitches that I may or may not fix eventually . . . .
Thanks for stopping by!
I recently purchased a MacBook Pro and got a new MacBook Pro at work, so I had two machines to set up. Here are the steps I went through to make these machines tuned for developing iOS applications as well as doing Java, Ruby, and Groovy development. I’d love to hear feedback on things I missed, things you don’t agree with, or things that didn’t work for you.
Starting Out — Basic Configuration
These are the basic items that, regardless of the languages you plan to develop in, you should do.
- Boot the machine, create your user, and use Software Update to download and install all updates.
- Go to System Preferences –> Keyboard, and on the Keyboard tab slide Key Repeat Rate all the way to the right. Check the box for “Use all F1, F2 . . . .” Click the Modifier Keys button and change Caps Lock Key to Control. Select the Keyboard Shortcuts tab and select “All controls” for Full Keyboard Access.
- In System Preferences –> Expose & Spaces –> Spaces, check Enable Spaces and Show Spaces in menu bar. Reconfigure for 1 row, 4 columns.
- Install TextExpander. Launch it and go to File –> Add Predefined Group and choose CSS Snippets, HTML snippets, and TIDBITS Autocorrect Dictionary.
- Drag everything you can out of the Dock, make it really small, auto-hide it, and put it on the left side.
You need a launcher. I used to use QuickSilver, and I always read that you can do so many powerful things with it beyond simply launching applications. I always meant to learn what those things are, but I never have and realize that I never will. I’ve been tempted to buy LaunchBar or F10 Launch Studio, but I fear I’d never learn the extra features and just use these apps to launch applications, and I can do that for free with Namely. Install it and go into its settings to map it to Ctrl+J.
I used to use iTerm for its tabbed windows, but OS X’s Terminal finally got tabs. You want a terminal window at your fingertips at all times, though, so install Visor, which is a dropdown, Quake-style terminal. Follow the installation instructions, installing SIMBL first then dropping the Visor bundle in the appropriate directory, and then map Visor to Ctrl+L and select its “Copy on Select” checkbox. Launch System Preferences –> Accounts –> (Your Account) –> Login Items and add Namely and Terminal. (Note: Namely has a preference to Open on Login, but that didn’t work for me).
File Backup and Sharing
Install Dropbox and either log in or register for an account. Be sure to enable Growl notifications during the installation.
The Rocketeers at Hashrocket use SizeUp to manage windows via the keyboard, and the same company offers a mouse-driven version called Cinch. I like Divvy, though. Install it, map it to Ctrl+K, and select to start at login. Create 4 shortcuts: Left 50% (A), Right 50% (S), Top 50% (D), and Bottom 50% (F).
General Development + iOS and Mac Development
- Create a directory in your home folder called Development. This is where all your development projects will live.
- Go to Finder and drag the Development and Downloads folders to the left side under Places.
- Install the latest Xcode. As of this writing, that’s Xcode 3, and Xcode 4 is available as a Developer Preview. Install both. Note: you must install Xcode, even if you don’t plan to write iOS or Mac apps, so that you can compile things like rubygems.
- Install Accessorizer and configure it according to its quick-start guide.
No direction here will spark more controversy than this one, so install the editor you like best. If you’re smart, though, you’ll install MacVim, and not just because it’s free (I’ve bought licenses to and used BBEdit and TextMate). Wait to configure MacVim in the Ruby + Dotfiles section.
Ruby + Dotfiles (Don’t Skip!)
Rogelio Samour from Hashrocket has written an excellent blog post on how to set up a Ruby and Rails development environment at http://blog.therubymug.com/blog/2010/05/20/the-install-osx.html. The instructions include steps specific to ruby and rails, but also steps for setting up your editor and dotfiles. Follow his instructions and ignore the ruby stuff if you don’t do ruby (though you should!). Note: here are my deviations from that page:
- Didn’t install SizeUp (I like Divvy better) or Teleport (I’m not pair programming in a shared-computer environment).
- Didn’t use Homebrew to install MacVim, but instead downloaded and installed from http://code.google.com/p/macvim/. I put the MacVim bundle in /Applications and the mvim command line in /usr/local/bin.
- Didn’t install RubyCocoa–I don’t use Rspactor, and I read that the latest version doesn’t require it anyway.
- Didn’t install Growl–Dropbox already did.
- Unless Ro has fixed it, he has a line that says to type
rvm gemset use 1.8.7@global. That gives you an error. Instead, type
rvm use 1.8.7@global. Thanks to Big Tiger (@jremsikjr) and Sandro (@sandrot) for figuring this out for me!
After you finish Ro’s instructions, do the following:
- Run this: echo ‘:colorscheme vividchalk’ > ~/.gvimrc
- Put this in ~/.vimrc.local:
set tabstop=2 set smarttab set shiftwidth=2 set autoindent set expandtab set number set directory=/tmp set laststatus=2 set scrolloff=3 set guioptions-=r set guioptions-=T
Some of these are redundant with the Hashrocket settings, but in case they change theirs . . . .
- Put this in ~/.gitconfig:
[push] default = current [user] name = (Your Name) email = (Your Email Address) [color] diff = auto status = auto branch = auto interactive = auto [core] excludesfile = /Users/(Your User ID)/.gitignore
Replace the parenthetical expressions appropriately
- Put this in ~/.gitignore:
Install Eclipse Helios from http://eclipse.org. It’s still the best Java IDE out there.
Follow these steps to install Groovy and Grails development tools:
export GROOVY_HOME=/opt/groovy export GRAILS_HOME=/opt/grails export PATH=$PATH:$GROOVY_HOME/bin
If you followed Ro’s instructions above, you’ve already installed Chrome and Firefox. If not, install them now. Launch Firefox and install the following extensions:
- Live HTTP headers
- View Source Chart
- Web Developer
Open Safari preferences, go to the Tabs tab, and for “Open pages in tabs instead of windows” select Automatically.
I’ve used Soho Notes and DEVONthink, but Evernote works across platforms, including iPhone and iPad, and keeps all the notes in sync. You can also access your notes from a browser. Anywhere you go, you can take and access your notes.
I tried not to use TweetDeck so I wouldn’t have to install Adobe AIR, but Balsamiq Mockups (below) requires AIR and I can’t find a Twitter client I like better than TweetDeck anyway. After you install TweetDeck, though, go into its preferences and turn off notifications (both detail and summary). You have work to do.
I used to use Adium, but iChat is already installed on your Mac and supports Google Talk, Facebook (through Jabber), and any other Jabber services. Configure iChat but be sure to turn off the sounds for buddies logging on or off.
I know of no reasonable competition to Path Finder. Install it and turn on its dual panes.
Install Balsamiq Mockups for doing mockups of web pages, client apps, iPhone apps, iOS apps, or whatever you need to mock up. Money well spent.
Mac OS X comes with built-in screen capture capability, but Snapz Pro X does so much more, including video capture.
I like to use a desktop client for blogging — it makes me feel safer, as I’ve lost plenty of text in my time to fickle web pages. I really can’t tell a difference between MarsEdit and ecto, at least the way I use them, so I went with ecto because it’s cheaper.
I’m sure OpenOffice is sufficient for most developers, but I have to use certain Word templates for work and writing, and create PowerPoint presentations for external consumption, that it’s not worth fighting any inconsistencies. Besides, I need Entourage for work. The work computer got MS Office Professional and my personal computer got MS Office Home. For the personal computer, I also had iWork pre-installed. Consider it my mini-protest. I’ll probably end up installing OpenOffice as well, in case someone sends me any .odt files (I don’t think Word can read those yet), but I’m holding off for awhile.
Install AppZapper so you don’t litter your disk with unused .plist files.
I’ve used several password managers, but I figured out some time ago that I want a command line tool so I wrote one in Ruby. To install, press Ctrl+L to drop down Visor and type:
- rvm use 1.8.7@global
- gem install safe
- echo ‘export SAFE_DIR=~/Dropbox’ >> ~/.bashrc.local
Note: when I ran this on one machine, gem install complained that it couldn’t find the crypt gem. I ran
gem install crypt and then
gem install safe. On the other machine,
gem install safe worked fine. YMMV.
You can read about safe, including how to use it, at http://grailbox.com/safe/. It’s beta software, use at your own risk, etc. I’ve been using it since 2007, though. Note that putting your safe file on Dropbox lets you run safe from all your machines, and it backs up (and versions) your safe file.
Web Site Development
I’ve looked at Coda, and I got a license to Espresso through one of the MacHeist deals, but I really haven’t figured out when I’ll use these. I want to, though, so my one concession to installing software on these machines that I don’t really use was Espresso. I’m going to make myself use it, and maybe then I’ll see the value.
What Did I Leave Out?
I’m such a software junkie that I install far more software than I use, so I disciplined myself to install only software that I’m currently using. Some software just barely missed the cut:
I’m still on week 1 of using these machines, and I’m sure I’ve missed plenty. These setup instructions, however, provide a rock-solid working environment. You may disagree with some of my choices — in fact, I hope you do, so I can find more software that other people are using to solve real problems. Don’t bother, though, to try to talk me into Emacs
I’ve added the following software this past week:
- Hyperspaces, which allows you to label and put different pictures on each of your spaces.
- OmniGraffle Professional for diagramming and interoperability with Visio.
- git-flow, the plugin to help with using Vincent Driessen’s git branching model.
- git-flow-completion — bash completion for git-flow.
- The NERD tree for vim. To install:
cd ~/.vimbundles git clone git://github.com/scrooloose/nerdtree.git
I’ve added some more software:
- I had some EPS files that I needed to resize and export to PNG. Inkscape, GIMP, and Preview proved inadequate, so I installed Pixelmator, which worked perfectly.
- I remembered DiffMerge from SourceGear. I always pay attention to what Eric Sink is up to, because he’s both bright and funny, so I installed that as well.
After reading this post on vim configuration, I can’t believe I’ve been navigating split windows with
- The RSS feed for this twitter account is not loadable for the moment.
Follow @hoop33 on twitter.
What I’m Writing
- December 2014 (1)
- November 2014 (2)
- October 2014 (1)
- April 2014 (1)
- March 2014 (2)
- January 2014 (3)
- August 2013 (2)
- July 2013 (2)
- May 2013 (3)
- April 2013 (6)
- February 2013 (1)
- January 2013 (1)
- November 2012 (6)
- September 2012 (1)
- August 2012 (6)
- July 2012 (10)
- June 2012 (4)
- May 2012 (7)
- April 2012 (4)
- March 2012 (8)
- February 2012 (7)
- January 2012 (7)
- December 2011 (1)
- November 2011 (1)
- September 2011 (4)
- August 2011 (2)
- July 2011 (2)
- June 2011 (2)
- May 2011 (4)
- April 2011 (2)
- February 2011 (1)
- January 2011 (1)
- December 2010 (3)
- November 2010 (3)
- October 2010 (4)
- September 2010 (6)
- August 2010 (96)