Release early, release often
"Release early, release often" is an agile development philosophy emphasizing the importance of early and frequent releases in creating a strong feedback loop between developers and users. It is in this spirit that I am publicly releasing WriteGreen, my work in progress app. I'd like to spend the bulk of this post describing what I've learned about development, versus describing what WriteGreen is about. If you want to learn more about WriteGreen, you can do so at the WriteGreen.org (the website and app are currently hosted separately for technical reasons).
Each of the headings below describe one aspect or another of my experience learning web development. I could write an entire post on each of them. However, these describe my experience more succinctly.
Halfway through my project, I switched from a Windows development environment to a Linux environment. Admittedly, Mac is the more popular environment to develop Rails applications. However, for my own personal reasons, I decided to give Linux a try.
Linux comes in many flavors. I installed the latest version of Ubuntu, 11.10. In switching, the biggest difference for me was Linux has a more developed ecosystem for Ruby on Rails. RVM, the Ruby Version Manager, is only available for Mac and Linux and is invaluable for developing on multiple versions of Ruby or Rails. I also found the Linux terminal to be vastly superior to the Windows command line. And since most servers run on Linux, I was able to get my app up and running 10x faster on Linux vs. on Windows.
Getting set up on a Linux was a lengthy process. I had to jump through many hoops, installing additional packages and hacking together solutions to get it to work as my main operating system on my old Dell Inspiron 1525. Still, with a little determination and a lot google searching, I was able to get it up and running to use it both as my personal computer and development environment.
Dell Inspiron 1525, Intel Core 2.0Ghz processor with 4GB of RAM and a 500GB hard drive
Operating system: Dual boot Ubuntu 11.10 on Windows Vista
Language: Ruby 1.9.2p290
Framework: Rails 3.1.1
Version control: Git
Editor: Gedit (after switching from Windows, were I used Notepad++)
Web server: WEBrick, then Thin
Hosting: Heroku
Iteration is at the heart of software development and design. Programmers and designers alike are constantly making decisions as to what forms their projects will take, just from two different perspectives. I like to think of it as software engineering and visual engineering. As the sole programmer and designer on my project, I was frequently revisiting my work, sometimes tweaking it, and sometimes scrapping it all-together and starting from scratch. This made for a much better finished product.
I iterated through various levels of complexity while building out my back-end and front-end. I started with the back-end, after all I need something to display. I then went through multiple iterations on both my back-end and UI. My first UI was just text output. I eventually graduated to two basic boxes with some basic CSS styling. Finally, I gave my app a facelift and created the UI it has now. However, it would be false to say I created 3 different UIs. In fact, I have been continously improving the UI over time. These three examples just give a taste of the various high level forms my UI took over time.
It is true that the "Release early, release often" mantra helps create a tight feedback loop between developers and users. In my experience, getting user feedback helped confirm some of my design hunches and uncovered new issues and insights to improve my app. Without such feedback I would have missed great learning opportunities.
There is atleast one bug that I know of within my application: the lack of form validations. If you submit a empty form or a form that contains an invalid address, the application will crash and throw an error. This is related to my implementation of the tabless models, which makes validation trickier (at least for a noob like me).
The dream of any software developer is to write bugless code. Nonetheless, the truth is that testing and fixing bugs usually accounts for half of the software development effort. There are steps one can take (like adopting agile development practices, and using BDD and TDD) that will help minimize the quantity and severity of bugs. My goal as a developer is to maximize the tradeoff between time spent on discovering and fixing bugs and the impact bugs have on the user experience.
My application is simple enough that it should not have any bugs (hope to accomplish soon). What I've learned about debugging is the importance of isolating individual components of my app. You can't fix a bug you can't identify, but knowing that a bug is present is not the same as identifying it.
Debugging tools can also come in handy depending on your philosophy. Some Ruby purists say debugging tools are unnecessary. Others use fully fledged IDEs (Integrated Development Environments), like Rubymine, a popular Ruby IDE. I tried Rubymine but found it to slow and unwieldy on my paticular setup. It ground my system to a halt. I'm guessing that my 4GB of RAM was insufficient for Rubymine, which is known to be a memory hog.
Cross-browser testing is hugely important as the number of browsers and operating systems grow. In addition to the latest browsers, software needs to be testing in legacy browsers. Ask any developer about the joys of accomodating IE6 and they'll recoil in horror.
Initially, I was frustrated that my HTML/CSS rendered differently in Firefox vs. Chrome, where I did most of my testing. I then realized that doing a CSS Reset solved most of my problems. A CSS Reset reduces browser inconsistencies in things like default line heights, margins and font sizes of headings, and so on, giving developers more control on how their site renders accross browsers. Still, even with a CSS Reset, it takes a bit of work to get the various browsers to display the same site consistently. I optimized WriteGreen for the latest versions of Chrome and Firefox.
While I've learned a lot, I still recognize many weak spots in my understanding of Ruby and Rails. Unless you have a really good understanding of the framework, deviating from Rails conventions can cause some pain. I spent countless hours implementing a tabless model in Rails, thinking it was a superior and simpler way to implement my project, only to find it pushed my understanding of the Rails ActiveRecord, ActiveModel and ActionController modules.
Furthermore, there is always a way to write cleaner code. To do so, it helps to have a solid understanding of typical programming structures and of the specific methods available in each language. I briefly spent some time learning Ruby before jumping right into Rails and found myself learning more Ruby as I went about developing my application. This meant I had some ugly and unyieldy code, like the following helper method:
def get_content(focus, focus_header)
max = count_variations(focus, focus_header)
counter = 1
text = ''
while counter <= max
text += ' ' + pull_entry(focus, counter, focus_header)
counter += 1
end
return text
end
An experienced developer like Anton Litvinenko, co-founder of 300.mg and with whom I consulted, can turn an eight line method like that into a one liner without much thinking about it:
def get_content(focus, focus_header)
(1..count_variations(focus, focus_header)).collect{|counter| pull_entry(focus, counter, focus_header)}.join(' ').squish
end
The developer community is always coming out with new tools, frameworks and extensions to make web development easier. One extension I employed on WriteGreen was SASS or SCSS. SASS is an extension of CSS3, adding nested rules, variables, mixins, and generally making CSS styling more pleasant. Best of all it translates into valid CSS and is surprisingly easy to pick up. HAML is another extension along the same lines, but for HTML/ERB. ERB stands for Embedded Ruby blocks. It is a templating system used to put Ruby code within an HTML file. I haven't yet tried HAML, but from what I read it creates more elegant HTML/ERB code. Elegant code = more readable code. That's huge for any developer.
Git is another critical tool I used for development. Git is a distributed version control system built by Linus Torvalds, the same guy that created the Linux kernel. It helps you track and manage the different versions of your code base over time and across collaborators. Even in my application, where I was the sole developer, it still saved me a lot of grief to be able to revert my code base to a previous working stage or to compare to earlier code.
I've found the development community to be incredibly supportive and helpful. In addition to all the open source tools, frameworks and extension they create, (which make development easier), they also make themselves available to answer questions on platforms like Stackoverflow and Quora. This is not only a relief for a beginning developer, but a necessity. Web development is only getting more complex over time, especially as developers need to implement test driven development, version control, back-end languages, front-end code, and so much more all within one project. Having good tools, frameworks and extensions helps control and manage that complexity.
In brief, I've come a long way from where I started, and I realize I still have a long way to go to become a solid web developer. Nonetheless, the skills and knowledge that I've picked up along the way have already given me a solid understanding of software development. This, no doubt, should serve me well as I continue to develop my technology career.