How Do You Make a Gem?

Posted on June 10th, 2010 by benhamill | No Comments »

This is not intended to be a how-to. I sort of talked a bit about that before. I’m writing this post because, as I breathlessly blogged before (alliteration!), I released my first gem. I then immediately turned around to start using it. And it was terrible. Yay for version 0.1! So I’m going to try something else.

The thing that sucked so bad was the API, basically. I didn’t really know how I wanted to use it or how best to fit it into a Rails app. I made a reasonable guess and got to work. It wasn’t a terrible first try, but it was a terrible API. However, I’m not sure what better looks like yet. And I think that I sort of got ahead of myself; I put the cart before the horse.

It’s a little like making the transition from drawing on paper to creating art with the GIMP. When you’re on paper, you draw the stuff that’s in front first and you only draw as much of the stuff that’s behind other stuff as can be seen. So you learn to think a certain way about how you build up your picture. In a program that has layers, you can draw in any old order and draw something entirely even if it’s obscured by something else in the long run.

I was thinking that the obvious path would be to develop my little gem of functionality and then use it in the larger Hey Go Vote application. Now I’m starting to think that’s backwards. I’m going to just work on Hey Go Vote and trust that doing so will give me insight into what parts of the announcement machinery can be made portable. Then I’ll extract those bits into a gem and refactor Hey Go Vote to use the new gem. I’m sure I’ll let you know how that goes.

My Git Talk At Austin On Rails

Posted on December 7th, 2009 by benhamill | No Comments »

At the last Austin on Rails meeting (Nov 17), I gave a talked entitled Practical Git Quickstart (Prezi link). The slides don’t have a lot of content and mostly underscored what I hoped to talk about. I blew through them in about ten minutes or less. The short of it is that I feel like a lot of git tutorials and introductions start off with the high-level stuff and that, especially for people new to git, that that’s confusing. My goal was to give git newbies the most basic commands they’d need to be able to use git on a daily basis so that they could build their own abstractions before diving into the more heady stuff. I was aiming for an 80% solution to that, anyway.

After I finished the slides, I fired up a command line and an editor and just worked through some stuff. This post should sum up what I talked about, more or less. I started out covering the same stuff I covered in my previous git tutorial post, so maybe go check that out first. It should get you through setting up a new repository, adding files to the staging area, making a commit, checking your status and committing to a remote repository.

So let’s pick up there, with remote repositories. The way you get code up to your repo is with git push origin master. Once it’s up there, other people can get at it. If you recall, you told git where your remote repo was going to be with git remote add origin git@github.com:<username>/<project>.git. Someone who wants their own local copy of your repo does so with the clone command like so: git clone git@github.com:<username>/<project>.git. That will create a directory wherever the command is issued, named &lt;project&gt; and pull down the current state of the remote repo. Then, that person will be able to push their own changes, etc. This is all, of course, assuming they’ve got permission to do so.

So this new second person makes some changes and pushes them on up. How do you get them? Well, sensibly, the opposite of push is pull, so you issue git pull origin master. This is actually a two step process that’s just for convenience. I don’t want to get into the plumbing too much, but it basically grabs the state of the remote repo (git fetch) and then attempts to merge (git merge) it with your local stuff. So that’s the most basic case of working with someone else on a project, or working alone on one using different machines, if you like. I use that case all the time.

So what about conflicts? If you both make a change to the same file and they push it first, you’ll not be allowed to push because git can’t handle the merge on it’s own. Similarly, if you try to pull, it will do the fetch part, but be unable to merge and will tell you so. You can use git diff to see what the changed were and do the merge yourself. You can also use git difftool which is awesome, but takes some setup, so you should look into it later on (I skipped it in my presentation).

Once you handle the conflicts, you’ll add the conflicting files to the staging area and make a commit. With all merges, I should note, git makes a commit just for the merge, so when you have conflicts, it’ll have staged the things it can merge on its own and left the conflicts unstaged. As you fix them, you stage them and then you commit the merge commit. Git doesn’t know if you really fixed the conflicts, so you can git add whatever version of the file you want, even a broken, not-conflict-resolved one. Just be aware.

That was more or less the end of my ordered presentation. There were some questions afterward and I’m going to attempt to sum up the discussion that followed, here:

First off, I wanted to mention how you ignore files in git. Unlike subversion, there is no git ignore. If you want git to ignore a file, you have to add it to a .gitignore file. This file is a list of patterns that git will ignore for the directory it’s in and all directories below it. So you might have one for a python project like this:

tmp/*
*.pyc

This will ignore all compiled python code (*.pyc) and everything in your tmp/ directory. I was baffled by this when I first came to git, but it’s not really that hard. Note that you generally commit your .gitignore so that others can share it. If there’s something you want to ignore on a per-machine basis, rather than a per-project basis, then you need to turn to my next topic.

Which is global git preferences. On Linux and Mac, git will look for a file in your root directory called .gitconfig and take global behaviors from it (it’s tricky on Windows, and I haven’t figured it out to my own satisfaction, sorry. If someone asks about it, I’ll try to sum up what I know in the comments). In my other git post, I had gone through setting up a repo on GitHub and said to follow the directions there. Two of those steps were these:

git config --global user.name "<your name>"
git config --global user.email <your_email>

Those created entries in your ~/.gitconfig telling git your name and email address. You can also declare a global ignore file there. I like to call mine .gitignore. This is shockingly original, I know. On the machine I’m typing on right now, my ~/.gitconfig looks like this:

[user]
email = blah@blah.blah
name = Ben Hamill
[core]
excludesfile = /home/ben/.gitignore

I bet you can guess it, but just in case, you can either put your excludesfile in manually or do git config --global core.excludesfile /whatever/file/path/you/want. For reference, my ~/.gitignore looks like this:

*.kpf
*.swp

A .kpf file is a project file created by Komodo Edit, which I used to use for all my code editing needs, but not since I switched to vim, which is what creates *.swp files.

Finally, someone had asked about git stash. It’s what I’d consider a more advanced command, but a lot of git fanboys sell it hard because it’s cool and svn doesn’t have it. However, as cool as it is, I think it can get you into a lot of trouble. Basically, you can be working on something and issue git stash and git will store whatever changes you’re in the middle of and hide them away, putting your repo back in the state it was right after the last commit. You can then work on something more pressing, make commits, merges, new branches, whatever and when you’re done, issue git stash pop and it applies your changes back (if it can).

The really hairy bit is that you can name stashes and so have more than one stash going at once. While a super organized developer might find this really useful, I find that it’s easy to get stuff lost in there. You don’t want to have tons and tons of stuff stashed and not remember, anymore, what changes were in which stash, etc. I advise, as a basic rule of thumb, that if you’ve already got one thing stashed and find yourself wanting to stash something else, then you should be looking at branching, not stashing.

I think that about covers it. I think someone recorded audio of my talk or maybe video. If it ends up posted somewhere, I’ll come edit this post with a link to it. If you were at my talk and notice something I talked about then that I haven’t covered here, let me know and I’ll try to amend. Or, if you weren’t there and feel there’s a topic you have questions about, drop it in the comments and I’ll do what I can.

New Side Project: HeyGoVote

Posted on September 14th, 2009 by benhamill | 1 Comment »

National elections, especially the Presidential elections, get a lot of attention in the US. People talk for months about who might campaign before people even announce their candidacy. There are news stories all over the place covering them. On the other hand, more local elections (for state reps or city councils, etc.) get a lot less coverage (because it’s not CNN’s job, for instance). Right after this most recent Presidential election, I realized that I hadn’t voted at all since the previous Presidential election. In four years, I hadn’t cast a ballot, and I thought I should probably become somewhat more involved in local politics. Or, if not involved, at least aware.

One of the buildings adjacent to the one where I work is a polling location. In Texas, that means I can vote there during early voting. A few months ago, I was cutting through that lobby and saw voting booths set up. “Oh!” I thought to myself, “I wonder what we’re voting on today.” I could have voted right then, but I had no idea what was on the ballot, what the various opinions and angles were, etc. It would have been totally uninformed and random, so I refrained, but I started thinking about how I could be forewarned about elections so I could do my own research.

I could start watching the evening news or following local (or state-level) political blogs or take the local paper. But that’s a lot of overhead which I’ve already decided I don’t want to deal with… and just to get one piece of data. So I thought I’d solve my own problem and the way I’d solve it (and solve it for people other than me, who think in a similar way on this issue) was with Twitter.

The Pitch

My initial concept was that I’d set up an app that would store election dates and just tweet them. I quickly realized that it’s a little more complicated than that. If I just tweet on election day, I’ve just recreated the oh-what-are-we-voting-on-today problem. So I need to give some warning ahead of time. @JonLoyens pointed out that a tweet can be easily missed, so I should use direct messages. The beauty, here, is that I can build a reminder service and not have to manage who wants reminders: It’s all just based on who’s following the twitter account.

So the idea is that you’ll follow @heygovote and it will direct message all its followers to warn that an election is coming up. Simple enough and if you want to opt out, you unfollow. Easy.

Three Rules

I want to keep these three things foremost in my mind while I’m working on this thing:

  • No Bias – I don’t want to help people decide how to vote, or influence their vote in any way. This is just about prodding people enough in advance that they can do their own research.
  • No Data – I don’t want to know who the users are and I don’t want them to have to trust me that I’m not selling information about them to some organization (related to the above, as well). So I don’t want to have to know anything about the user other than their Twitter user name and I don’t even plan on storing that, just asking Twitter who’s following @heygovote.
  • No Bother – I don’t want to hassle people. I want to remind people, not badger them. I also don’t want to have to mess with the thing myself to keep it running; it should be fire-and-forget.

Trouble Scoping

It pretty quickly became evident that I needed to decide who my target was. I’d intended to target “Austin”, but that doesn’t really scale gracefully to the county, state and national levels. After talking to my brother, who works on campaigns and the like, I’ve decided I’m going to target Travis County. That catches most of Austin (more to the point, it catches where I live, since this is solving my problem) and also scales up nicely.

For voting purposes, Texas breaks counties up into voting precincts. All the election dates for all the precincts in a given county are the same, so one tweet (or, rather, direct message) will apply to everyone in Travis County. If, beyond comprehension, this becomes wildly popular and other places want HeyGoVote to cover them, then I’ll deal with that as it occurs. My guess is that how elections are handled will be different enough from state to state that it would mean rebuilding the date-getting machinery for each, uh, constituency, as it were.

Where to Start

I haven’t started coding on anything yet; all work to date has been design thinking and research on how I can get a hold of the information I need. I’ve sent some emails back and forth with the Travis County Tax Office (which decides election dates, oddly enough), who’ve been helpful. They don’t seem to have a handy RSS feed of election dates that I can poll, so I’m still working out that side of things.

I will probably start on the reminder side of the application. If I design the DB schema intelligently, it can be very loosely coupled with the data gathering bit. Depending on how it goes, it also seems like the kind of thing that might make a useful Rails plug-in, too. So I might release that on it’s own.

That being said, I expect to use Rails as the tool set. That might seem like overkill since nothing I’ve described has needed a web interface to it, but I have the idea that, after I get the reminder working, it might be nice to build a tool or two that would help people figure out where their polling location is (for folks who skip early voting), what’s on the ballot for their precinct and things like that. If I can’t find existing, non-partisan tools to link to for this, I might have to build my own.

Expect to hear more about this as I work on it. If you have any suggestions or questions, leave a comment.

Bad & Getting Away With It

Posted on April 30th, 2009 by benhamill | No Comments »

There’s been tons of hoopla about these slides that some guy showed at GoGaRuCo . Seriously, so much hoopla that I’ve been unable to absorb the guy’s name (note: I have a really, really hard time with names as it is, so…). Also so much hoopla that I don’t even really know what to link to so that people will have an idea of what I’m talking about if they don’t already. I guess _why did a decent job of explaining it by not explaining it. The short story is that there were some slides in a presentation with very scantily clad ladies doing very suggestive things. Everyone’s freakin’ blogging about it and I hate to me-too this thing, but I do want to express a thought I haven’t seen yet and I also neglected to make a post this month, which has been bugging me.

And Now, a Tangent

So in college, I played trombone in the marching band. It was good times and we had this principle that we called The Stupid. This may not make perfect sense to people who haven’t experienced band social dynamics first hand, but I’m going to try. Basically, the trombone section had a reputation amongst the rest of the band (360ish total members) for doing ridiculous, stupid things for no reason. It had been decided amongst ourselves that, rather than try to live this down, we’d just run with it. So we did Stupid things on purpose; frequently to humorous effect. I mean–we were always entertained, others were only sometimes entertained.

That was the big flashy visible part of the Stupid. We got elaborate, spending large percentages of our meager college student incomes on Stupid ideas that we planned for weeks. We went to great lengths. The part of the Stupid that wasn’t so visible was the great lengths we went to to ensure that we didn’t… inflict the Stupid on anyone who didn’t opt in. We had the goal of making so that if you missed some prank (or whatever you want to call it, not all of it was traditional pranks) of ours by a few hours, you’d never know it happened. We had varying levels of success with it, of course, but I think we did a pretty good job.

We also tried to go to Stupid lengths to be helpful to the band in general; we’d help clean up or take care of something that we saw needed doing rather than just waiting for someone else to do it or reporting it or whatever. I should point out that the directors found the Stupid highly unamusing in the way that I think is probably appropriate for teachers to find the antics of their students. Taking care of things and working hard was sort of our effort to come out net neutral in their minds and not get in hot water.

So the ‘bones weren’t nationwide (well, the Stupid did get on ESPN in the background a couple times and of course we were on TV performing at games, but not for our antics, generally), as Giles says, but we did have a reputation for being bad and (the key to being bad) getting away with it.

The Moral of Our Story

So, as things go in college, people get older and graduate and new folks come in, etc. Traditions shift and change. There came a day when some new kid was really jazzed up about the flashy, visible, bad part of The Stupid and didn’t have the working-hard, cleaning-up-after-yourself, help-others-out part of the Stupid down so good. Basically, he was seeing the bad and didn’t see what let us get away with it. And he (I’m actually talking about several people over a period of time and series of events) did something he thought was Stupid, but was just stupid. He got on people’s nerves, got in people’s way, maybe he broke something that cost money… and he didn’t do anything that would make people think, “Well, that’s alright, because… whatever.”

So I hope you see where I’m going by now. Amongst Railsers (as a broad generalization and as distinct from Rubyists) there’s a bit of a tradition of being bad. DHH is, arguably, the originator of that attitude and he’s certainly been an icon of it. I’m not even saying he’s wrong. I’m saying that whenever you have people like him (and he is, I should stress, not alone, here, Cf. Chad Fowler, Giles Bowkett and Zed Shaw) there will be others who look up to that way of being, who idolize it, who imitate it, but who, ultimately, don’t get it.

These freshman, as it were, will do the flashy, visible, bad part of the image (perhaps poorly, but perhaps not) but neglect to do the more subtle things that let their idols get away with it. I’m not sure what it is those idols are doing, specifically, that makes up for their behavior (they certainly aren’t practicing their music the most). I suspect that, really, everyone has to find their own way to make up for acting like a jerk.

What I’m driving at is that if you’re setting an example (as anyone highly visible in a community is) for being so awesome that no one minds when you’re a jerk, you have to take a bit of responsibility when others imitate you and screw it up. I think Matz chose (probably by nature, rather than consciously) an easier path: If you set an example of being humble and nice and people imitate you and fail, they’ll at least have the safety net of, “…well, his intentions were good.”

My Twitter Project: atreply

Posted on February 10th, 2009 by benhamill | No Comments »

I use Twitterfox to read and create tweets most of the time. I follow enough people that, when I open my browser for the first time for the day, more than 20 tweets have accumulated and, really, I don’t want to go back and read all 60-odd or whatever that have accumulated overnight. Twenty, I should note, is just what Twitterfox picks up when it first turns on.

Occasionally, I’ll come in and see the last few tweets in a conversation between two people I’m following (I only see @replies by others who are to people I’m also following). If it seems interesting enough, I’ll go back and page through to see what they were talking about, reading in reverse order. Sort of like reading a chat log written by the guys that made Memento. It’s not horrible, but neither is it ideal.

So I had an idea about it and I’ve started work. Twitter tracks what tweet (technically called a “Twitter status”, apparently) any given tweet was a reply to. And, I figured, it would be relatively simple to, given a Twitter status ID, recursively follow the reply chain back and get the whole conversation. Turns out, I was right.

A proof of concept:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
require 'rubygems'
require 'twitter'
 
class Reply
 attr_accessor :text, :author, :in_reply_to, :time, :atreply
 
 def initialize status_id
   status = Twitter::Client.new.status :get, status_id
 
   self.text = status.text
   self.author = if status.user.name then status.user.name else status.user.screen_name end
   self.time = status.created_at
   self.in_reply_to = status.in_reply_to_status_id
   self.atreply = Reply.new self.in_reply_to unless self.in_reply_to.nil?
 end
 
 def each_reply &amp;block
   reply_chain.each do |reply|
     yield reply
   end
 end
 
 def to_s
   self.author + ' - ' + self.time.to_s + "\n" + self.text
 end
 
 protected
 
 def reply_chain
   return [self] unless self.atreply
 
   self.atreply.reply_chain &lt;&lt; self
 end
end

This has a dependency on Joshuamiller’s version of twitter4r. My medium-term plan is to make a one-trick-website that will take an ID or twitter URL and give you the replies all pretty-like. Maybe make a bookmarklet for convenience’s sake. I plan on using Rails, even though that’s overkill because I figure it’ll be a good learning experience on that front. Find it on Github.