My recent blog post on ideas for beginner web developers generated a bit of a buzz. It’s interesting to see that so many people want to learn how to program yet don’t know where to start. Some people would assume that if you want to learn how to program you already have something in mind that you want to accomplish. Sometimes that’s right, I always kind of wanted to build a computer game. Other times it’s just because you want to learn a valuable skill. This logic was what brought me to becoming a web developer fulltime.
If your focus is on desktop applications there are many different approaches you can take. You’ll initially want to build command-line applications to get a handle on managing data and manipulating it. As you progress, you’re going to start to want to make this data visible and begin doing user interfaces. After that, integration with web services is always fun.
Here’s an approach that I would recommend to someone starting out as a desktop application developer. Focus on recreating the basic tools you would take for granted in the future. I would suggest doing all of this in a scripting language like Ruby or Python. You will have a considerably harder time learning the concepts in C++ as you will be learning at a much lower level. If that’s your thing, go for it, the real goal is to work on something you enjoy.
So without further adieu:
- Almost every application has configuration settings somewhere, so build a configuration parser from scratch.
- It’s pretty imperative that you start simple, so take that configuration parser you just built and make a command line todo list. Load and save the todo items using your config parser.
- Now that you’ve got some basic input/output done, let’s sophisticate it a bit and instead save the data to an SQLite database. Lots of desktop applications use these, and it’s just good practice to know how to work with databases anyways. Just use raw SQL statements to write your data.
- Let’s take a step back and clean up the database code this time. It’s not really good to write raw SQL. What you typically want to do is create classes in your code that represent objects in the database. This is called an ORM. Build a basic one of these so that you can set properties on the object and it will automatically update the database without the program needing to understand that it is being saved to an SQL db. Bonus points if you make it support multiple database types.
- Now that you’ve gotten your hands dirty with a lot of different backend things, it’s time to put a pretty face on what you’ve built. Check out Cocoa if you’re a Mac user, GTK or Qt if you’re on Linux or Windows. Compare the GUI toolkit options and figure out what is best for your application. Do you want it to run on any OS? Do you hate how a certain one looks and feels? Experiment, even how writing code for a toolkit feels will have serious effects on how your application turns out.
- Very cool, now most applications are becoming web friendly. Nobody wants their data stored on a single machine, they want it everywhere. Look at any of the websites you use on a daily basis, maybe you use Twitter. Instead of using the official Twitter client, try to build your own that works with the Twitter API. Don’t just build it, but actively use it, open source it, try to get your friends using it. You’ll quickly realize that there is a lot to GUI programming, especially the little tweaks that make an experience go from mediocre and annoying to smooth and exhilarating. The most important part is that you use your own software. Things that bug you most certainly will bug other people. Having other people use your software will make things that you overlook come to the forefront so that you become aware of them. Remember that you’re looking through developer’s eyes, not a user’s.
I feel that if you take an approach like this, you get an appreciation for the underlying libraries that most seasoned developers take for granted. Yes they don’t think about the libraries they use too often, but if anything goes wrong they can already have a good understanding of how it works. This is what you want, enough knowledge to be deadly but not too much that it’s overwhelming.
I took this approach with
Keryx. For 4 years, I spent an incredible amount of time trying to build everything from scratch in Python and essentially recreate Synaptic on Ubuntu on my own while simultaneously adding offline support. It’s a huge undertaking and I don’t feel like I ever got it truly finished. At the same time, it has landed me a magazine interview in Linux Journal, humbled me by the incredible heartfelt thank you’s that people have written, and given me huge respect for the community.
This might be just a personal note to myself, but don’t ever become afraid to put your work out there, it is the only way to truly learn. The more you learn, the more you might become afraid that you’re doing seems wrong. It feels like someone might criticize your approach and call your code crappy, but guess what? You built something real and got feedback. If you never showed it to anyone, you’d never know that you could have been doing a better job. Open source your projects on github and get people involved even if it’s just friends. You’ll learn leaps and bounds faster than on your own.
Rails 3.1 final is just around the corner. As I’m eagerly awaiting the release of this version, I’ve begun writing a lot new Rails projects in 3.1. The problem with this is that quite a few libraries are only really built for Rails 3.0 at the very latest.
Tonight I wanted to try Omnisocial. I know that Omniauth isn’t that hard to setup on its own, but hey, might as well try new things right? Well, I ran into some problems. After setting up the Omnisocial gem in my Gemfile I fired away at bundle install but ran into this problem:
omnisocial depends on multi_json (~>0.0.2)
Nice. Something in Rails 3.1 was conflicting with the version of multi_json that one of the Omnisocial dependencies. That fix was easy enough.
Now, Omnisocial works, but login with twitter no longer works. After some fiddling, I came to the conclusion that it wasn’t a problem with my configuration, or at least not likely.
I came across an issue on Github for Omniauth (Unforunately I don’t remember which one). A bunch of people were also having failed logins with Omniauth as well. It certainly didn’t seem to be a standalone issue with Omnisocial at this point. One of the comments mentioned that rack.auth had been changed to omniauth.auth and then it clicked. This was the reason, it was probably just getting a nil instead of throwing an exception and causing everything to fail. Sure enough, that’s what it was.
While we wait to get the official Omnisocial repo updated, you can go ahead and use my version.
Updating libraries to Rails 3.1 compatibility is fun, important, and lots of people will thank you for doing so. It’s a great way to learn. If you have a plugin that you need help converting, let me know! I’d love to help.
The more you start working with Git, the more you’ll want to become a Git Grand Master and join the ranks of Linus Torvalds. Typing git status all the time not only wastes away the precious hours of your life, but its certainly no way to impress your coworkers, convince your boss that you came from another universe, and certainly won’t impress the cute secretary.
But what if…just what if…you could integrate it into your command prompt? That might be the final straw so you can get a raise AND a girlfriend right?? Hell yeah! Let’s do this!
# http://henrik.nyh.se/2008/12/git-dirty-prompt
# http://www.simplisticcomplexity.com/2008/03/13/show-your-git-branch-name-in-your-prompt/
# username@Machine ~/dev/dir[master]$ # clean working directory
# username@Machine ~/dev/dir[master*]$ # dirty working directory
function parse_git_deleted {
[[ $(git status 2> /dev/null | grep deleted:) != "" ]] && echo "-"
}
function parse_git_added {
[[ $(git status 2> /dev/null | grep "Untracked files:") != "" ]] && echo '+'
}
function parse_git_modified {
[[ $(git status 2> /dev/null | grep modified:) != "" ]] && echo "*"
}
function parse_git_dirty {
# [[ $(git status 2> /dev/null | tail -n1) != "nothing to commit (working directory clean)" ]] && echo "☠"
echo "$(parse_git_added)$(parse_git_modified)$(parse_git_deleted)"
}
function parse_git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/[\1$(parse_git_dirty)]/"
}
export PS1='\w$(parse_git_branch)$ '
What is this I don’t even? Okay, well, you need to put this in your .bash_profile or .bashrc file. Re-open your terminal and you’ll have your new sweet prompt all ready to go. When you’re in a git directory this code will execute and you’ll get a neat little addition that shows your current branch, additions, deletions, and modifications.

How sweet is that? Here we’ve got a screenshot of my prompt in the Fluttrly source directory. (Subtle advertisement here for contributions to Fluttrly)
Provided you actually use git to a tiny bit of its potential, this is really awesome. If you don’t, well, why don’t you go use Visual Studio, we don’t want you here I guess now is the time to learn. Works on any bash prompt with colors enabled.
Of course you could just use zsh for all this, but that’s for another time.
Okay, so maybe this isn’t the coolest thing in the world, but it is pretty freakin handy. Comment if you have a cool prompt you’d like to share. I need to get my nerd cred up at work.
I don’t know exactly what happened the other day, but I ran a git diff and instead of the usual red and green colors, everything was some form of ESC[32m ESC[1m ESC[m and so on in order to tell the terminal to switch colors.
ESC[1mindex 6008531..985ce31 100755ESC[m
ESC[1m--- a/bin/build-site.pyESC[m
ESC[1m+++ b/bin/build-site.pyESC[m
ESC[36m@@ -1,5 +1,9 @@ESC[m
#!/usr/bin/env pythonESC[m
ESC[m
ESC[32m+ESC[m
ESC[32m+ESC[m
ESC[32m+ESC[m
ESC[32m+ESC[m
import getoptESC[m
import gitESC[m
import osESC[m
Okay this is just great. No idea what is going on, and I can’t possibly continue coding like this. After a bit of googling, there wasn’t much on the situation.
It turns out that the less command got misconfigured. I was working on Ubuntu and found the culprit to be the $LESS environment variable misconfigured.
$ echo $LESS
-eiMX
$ export LESS="-eirMX"
These two commands in terminal will print out the $LESS environment variable and then set it. The “r” option is what is crucial here. It’s what enables coloring in less output. Another environment variable you may look at is $PAGER.
Take a look here for a really good description of the problem: http://www.xcombinator.com/2008/07/23/mac-os-x-color-showing-escwhatever-for-git-diff-colors-and-more/
A couple days ago I was contacted by Adam Doupé regarding a vulnerability he had been researching for his PhD. He had been scanning Github projects for the vulnerability and had found what could possibly be an issue on Fluttrly.
While Fluttrly was actually unaffected, the vulnerability is a serious one. When using a web framework such as Rails or Django, your “redirect” statement actually just generates a Redirect Response. This does not halt the execution chain which leaves the rest of your code to continue execution when you probably wanted it to stop.
Here’s an example from Adam’s blog:
class TopicsController < ApplicationController
def update
@topic = Topic.find(params[:id])
unless current_user.is_admin?
redirect_to "/"
end
if @topic.update_attributes(params[:topic])
flash[:notice] = "Topic updated!"
end
end
end
With this code, a user can still change the topic even if they aren’t an admin because authorization of the request isn’t handled properly. The code looks correct upon first glance, but it is subject to anyone changing the topic.
The solution Adam suggets for this is to redirect and return on the same line in your controller. That’s fine if you need to do a redirect in your controller action, but it’s not a best practice, at least not for Rails.
The best remedy for this is simply to use filters in Rails. With a before_filter, you can check if the user is an admin and redirect accordingly:
before_filter :admin_required
def admin_required
redirect_to "/" unless current_user.is_admin?
end
This will halt the chain before the code in update begins execution because of how Rails’ before filter’s work.
While this is just an example before_filter, you should really check out using a Rails authorization gem like CanCan. These gems allow you to configure user levels and the functionality they are allowed to execute. They provide a much better way to manage and configure authorization without overhead of having all of the code to handle this in your application.
I’m glad Adam is disclosing this to people. It’s something that is easily overlooked and it’s good to raise awareness of these things to new Rails developers.