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 First Ruby Gem

Posted on May 7th, 2010 by benhamill | 1 Comment »

I just released my first ruby gem, twitter_alert. It’s intended to be a component of the side project I mentioned forever ago, HeyGoVote. It grabs all the followers for a Twitter account and DMs them a message. The messages have dates on them because their intended to be schedule ahead of time. I’ll crib from the readme near the end, but if you want, you can go read the whole thing for yourself. First, I’m going to talk a bit about my experience writing my first gem.

Jeweler

I used the jeweler gem to create a gem template for this guy. It’s very simple and was a huge boon considering this was my first time. It scaffolds out the directory structure for you, sets up some handy rake tasks and generally gives you guidance on how to structure your gem. The readme for jeweler is very helpful. I won’t bother to restate what it says, but seriously, new to gems or not, you should have a look at jeweler if you haven’t already. One of the nicest things is that it’ll generate your gemspec file for you and also handle version bumping in a semantic versioning compatible way. It also integrates with git and GitHub in some interesting ways.

Gemcutter

Jeweler will also handle publishing your gem to “gemcutter” for you, which is nice. I say that in quotes because, of course, gemcutter.org is no longer a thing and their stuff all got officially adopted by rubygems.org, so it actually publishes to there. The jeweler documentation, though, all acts as if gemcutter were still a separate thing. This could be potentially confusing, I guess, but it ends up working right, so it’s fine. It does use the gemcutter gem to manage the publishing, so you’ll have to have that installed, and make sure you have a rubygems.org account and api key set up. The api key goes in ~/.gem/credentials as you’ll learn on your rubgems profile.

twitter_alert

I’ll crib from my readme example to show the most basic setup:

1
2
3
4
5
6
7
8
9
10
11
require 'twitter_alert'
 
account = TwitterAlert::Account.new :user_name => 'benhamill', :password => 'thisisnotmyrealpassword'
 
class Alert
  include TiwtterAlert::Alert
end
 
alert = Alert.new 'Very important message.', DateTime.now
 
account.announce alert

In the wild, I don’t imagine that your Alert class will be so simple. For instance, when I plug this into HeyGoVote, it’ll be included in an ActiveRecord model so I can run a cron job that pulls out tweets that should go out today (based on the date) and sends them all.

I haven’t plugged this into code yet, and note the version number 0.1. The tests pass, but they may not be comprehensive and I might have botched something up in my publishing, but it looks like everything’s working to me. My next step is to start building up HeyGoVote and using twitter_alert in it, which might reveal some needed features. In the meantime, I welcome feedback. Leave a comment here, or fork it and issue me a pull request, if you have an idea.

Vi Improved

Posted on November 25th, 2009 by benhamill | No Comments »

I recently started using vim on my Linux machines for development (actually gvim and I just haven’t gotten around to installing it on my Windows partition). I’d tried to learn it some time ago with the understanding that it’s awesome, but it didn’t catch on. I know a lot of smart people who use it and it was always one of those things that I felt would be really valuable for me to learn, but–it was hard.

Well, now it’s easy. @adambair mentioned this blog post by Derek Wyatt. It’s a collection of videos he made introducing you to the most basic commands in vim. Enough to get your feet under you so that further research on your own has something to stick to. They’re awesome.

However, the reason they’re awesome is not just that he takes you step by step through the most important stuff or that he’s lighthearted and friendly-sounding. The awesome part is that he shows you why it is that vim is so raved about. If you try to learn vim thinking that it’s like TextMate or NotePad or something, you won’t get it. And until you get it, there’s very little impetus to get over the learning hump (or through the dip, depending on which way you chart things in your head).

The key to understanding, for me, was realizing this: You should not be spending most of your time with vim in insert mode. You should not be typing and selecting in the sense that Word teaches. You should be doing finds and replaces and yanks. You should be operating on your code with macros. If you’re writing new code, great. You’ll be in insert mode for a while, but even then, you’ll want to invoke something that’ll set up your class structure with maybe some default methods in it or something. And as soon as you’re done, you’ll want to be jumping around by line number, moving to a specific character in a line, replacing a segment of a line with two keystrokes. Really, just the movement possibilities blew my mind. So, go watch the introduction.

Feedback Wanted: Blog Topic

Posted on October 1st, 2009 by benhamill | No Comments »

You read my blog, right? I mean—here you are reading it. I’ve been having an internal debate for a while about something, wondering what people who read my blog would think. Then I realized there’s a wonderful way to find out: ask.

So far, Garbled has been mostly about programming stuff. I also do a fair amount of table-top role playing and since I started blogging, some of my ideas on that topic have ended up sounding like they might be worth a blog post. But I don’t really have a role playing blog. In considering whether to post about both topics on Garbled, I’ve got two conflicting things going on:

  1. People say you should pick a topic and stick to it if you want to build readership. By this advice, I should talk only about programming here and find another place to post role playing thoughts.
  2. My thinking about programming and about role playing happen in adjacent or overlapping regions of my mind, so, to me, they are somewhat complimentary. I sort of feel like seeing both those lines of thought paints a (more) complete picture of me as a person.

So what are your thoughts? Would a rare or uncommon post about role playing in general or maybe GURPS in specific be alright? Considering that it would mostly probably be about plot construction and other GM related activities. Or should I stick to programming and programming-adjacent topics? Let me know in the comments.

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.

The New Breed of Hacker

Posted on June 9th, 2009 by benhamill | No Comments »

In light of my last post, I got to thinking some more about old school hackers. Also, at my job, we’ve got some people who’ve been here a long time. One in particular, we’ll call him Steve, is very smart, but… And, see, that’s sort of the thing: I can’t put my finger on it exactly. Steve is blazingly smart. But there’s clearly a difference between he and I that isn’t, I think, just accounted for by the 20 or so (I’m guessing) year difference in our ages.

If I see something I dislike—something that could be better—I really want to see it change. I want to be involved in that change if not driving it. Steve is often watching and present. He’s paying attention mostly and if you ask him a question he’ll have an insightful answer. If someone proposes a change that’s actually a good one and addresses a real problem, etc. etc. he’ll be glad the change is coming. But he never pushes for it. He never starts a conversation (in the wider sense, I mean; he will say hi to you in the hall or whatever) and hardly chimes in unless addressed directly.

And I think Steve fits a sort of archetype. He’s very interested in low-level details (well, actually in almost any kind of technical detail). He seems to be pretty much interested in being left alone and tinkering in his shop to see how things work (to use a light metaphor, here). If something is bad or less than optimal for other programmers around him (and including him), he’ll either ignore it or work around it on his own. His solution wont be general enough to apply to everyone, though and he wouldn’t publicize it. He’s very internally focused. And I associate this stereotype with older programmers or, more accurately, with old school programmers (how long have you been coding, not how long have you been alive).

On the other hand, I think think there’s a newer breed of programmer that’s becoming or has become very common. And I want to be very specific, here: I’m talking about hackers; folks who code because they enjoy it, not those who do it because its their job. People who would code to solve computer-related problems they have at home even if they were a news anchor or a trail guide. This new breed is more externally focused. We want our solutions to problems to be useful to other people. We want to have a conversation and (often) change the way things are done (for what we see as the better). We want powerful abstractions and like to live up away from the metal, generally.

I haven’t cataloged all the differences and, in particular, I’m having a hard time figuring out the attributes for my “new breed” of hacker are. Of course I’m talking about generalizations and stereotypes, here, but I don’t think that’s intrinsically bad. Basically, I get a sense of a certain amount of cohesion in personality type and behavior in these two groups and it struck me as interesting. What do you think, am I drawing a distinction where there is none? Is this distinction useful for anything? Is there some interesting point I’ve missed?

The Happy Hacker

Posted on June 5th, 2009 by benhamill | No Comments »

You frequently hear (or I do, anyway) the advice that if you’re unhappy in your coding job, you should scratch your own itch, work on what you love… Work on something you’d be a user for. Because then you don’t have to do a bunch of requirements gathering and get them inevitably wrong, etc. etc. The idea seems to be that if you love the business process, you’ll love working on the code that enacts it. And, well, that’s fine. It seems to make a lot of sense, on the surface. But then I thought about history.

As programmers, we don’t have a lot of it (compare auto workers or, say, masons). History, I mean. But there’s some and in the days of Mel and COBOL Cowboys, things were different from what they are now. Today we have all these powerful abstractions and high level languages. Folks (well, not all, but many) consider it to be ideal if you’re basically writing your code in a DSL specific to your business process. Which means your code is really tightly coupled to your business (on that layer, anyway). I don’t know that that’s a bad thing at all (in case I sounded critical). I just want to contrast it to what came before.

Those dudes were almost just writing ones and zeros. They were so far removed from the business processes they were enacting and the folks who were using their stuff that I wonder how much impact it had on them. Would Mel have been any more or less happy writing financial management apps for large companies than solitaire? I kind of think it wouldn’t have mattered to him; he was in it for the code and playing with numbers. He enjoyed all that low-level stuff.

So I wonder, is our (figurative us, here) unhappiness when dealing with business processes we aren’t personally invested in a symptom of all of our awesome high level languages and nice abstractions?

Git Tutorials Suck, A Sucky Git Tutorial

Posted on March 18th, 2009 by benhamill | No Comments »

Context… Perhaps Too Much Of It

So I was reading this blog post about learning and explaining because @carl_youngblood tweeted about it. I think Carl’s right: I had a hard time learning git (by which I don’t mean to imply I’m some sort of expert now, but the learning is going easier now).

I think the main problem that I had was this: Having learned Subversion, with it’s central repository, it was a hard abstract thing to understand. And some (I feel many of the ones I read, anyway) of the tutorials out there try to start at the abstract. Little help that did me (see above-linked article. Really, it’s very good). And even ignoring those, I had to read a lot lot lot of the practical ones before things started sinking in.

So I’ve sort of come to understand that, actually, the tutorials don’t suck; learning abstract things just takes time and, at the time, that can be frustrating. So I’m going to offer my own little sucky tutorial, which will focus on the practical aspects and, if you read this and don’t get it, you can follow some links at the end to other articles I found helpful and maybe, after roughly a week, you’ll have your ‘ah-Ha!’ moment and think about how git is just like monads… whatever the heck those are.

A lot of tutorials for git newbies start out explaining the Staging Area with some kind of metaphor so that it seems friendly or, I suspect, out of some subconscious wish to actually obscure it from Subversion converts so that git seems more familiar–more like SVN, which it is not very much like at all. I’m not going to really talk about it much. When we get to the commands that affect it (shortly, here), I’ll explain what they do. You can make the abstraction your self.

I’m intentionally writing this off the top of my head for two reasons: If I have to look up a command, then you might as well read whatever tutorial I looked it up on and if I have to look it up, then I clearly don’t use it all the time and thus, you don’t need to know it to get going on Git.

The Tutorial

I’ve got six sections to this thing with (I hope) at least vaguely descriptive names. They are:

  1. Setup
  2. Initial Commit
  3. SitRep
  4. Staging Area
  5. Remote Repo
  6. Conclusion/Links
Setup

You have a project you just started in a directory called ‘notes’. This isn’t even code, it’s just notes about something that you want to version control and back up. It’s a collection of text files and the directory structure is something like this.

$ pwd
~/notes/
$ ls
contact_info.txt  general.txt  outline.txt

After installing git as appropriate for your operating system, you start out by typing in the command line git init. This will create a directory called .git in notes/. There’s some stuff in there, but for the most part, you can ignore this for now. Suffice to say it’s where git does it’s book-keeping. What you’ve got now is a local git repository or, as the kids say, a “local repo”, but nothing’s in it.

Initial Commit

So you do a git add . (note the trailing period). This will toss everything (that’s what the period means) in notes/ into the staging area (including stuff that’s in directories that’re in directories that’re in notes/ etc.). The repo is still empty. To actual save stuff once it’s been staged, you do like this:

$ git commit -m 'Initial commit.'
[master (root-commit)]: created 7db8343: "Initial commit."
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 contact_info.txt
create mode 100644 general.txt
create mode 100644 outline.txt

The -m option says you’re going to specify your commit message right after. Sometimes, you’ll want to leave a longer message, in which case, you forget the -m and git will automatically fire up a default text editor where you can put in longer stuff. Since a lot of that varies widely from OS to OS, I’m going to skip it and you can read more details on other tutorials (see below). Notice that you get a list of what’s changed (you created 3 new files in the repo) and you get your comment back in the output. Splendid.

SitRep

Now you’ve made your initial commit, and your stuff is in version control. Go into contact_info.txt and add something (doesn’t matter what for these purposes). Imagine you’ve made that change and then walked away and forgotten about it. You can use git status to see what’s new, thusly:

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   contact_info.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

Using git status is just like a reminder. It doesn’t tell you much, but it can jog your memory about what you’ve already staged or what you changed and didn’t stage or what files you added. To get the real scoop about how a file changed, you use git diff. When you run git diff contact_info.txt the output will vary depending on what you had initially and what you added, but the gist is this: It will show you the changes (all of them) with a + before the line for additions and a – before the line for deletions. Generally, it gives a few lines before and after a change for context.

So let’s add our new contact_info change to the staging area and commit it, yeah? Do git add contact_info.txt and then git commit -m 'Updated contact info' or similar. Whatever comment you write is fine. Note we could’ve used git add . but I wanted to show the single-file syntax.

Staging Area

Now let’s put in some stuff into the outline.txt. Whatever you want. Just some stuff. Save it. But wait! We should also add some stuff to the general notes, just a quick overview at least, so put some stuff in there. We’ll finish the outline changes in a second. This is so much more pressing. Obviously.

Now, it’s good repo etiquette to only commit stuff atomically, which is to say that all the changes have to do with each other. Some people will say that you should only commit stuff that works (code compiles or whatever), but with git that’s less of a concern. I’ll come back to this point. What I’m getting at now is that you started one change and realized another needed to be made before you finished the first one. Now you want to commit only the second one, right? Simple: git add general.txt then git commit -m 'Added overview'. Because you never staged the outline (with your half-way-made changes), it doesn’t get committed. Later, if you need to revert that commit or whatever, you won’t have to worry that something else is mixed in there. Now, go ahead and finish your outline changes, and commit them. You should be able to do it on your own now.

Remote Repo

So, then… we’re version controlling this stuff. What if you want to get at it from another computer or let someone else get at it or… something? Pop on over to Git Hub which is my remote repo host of choice. There are others. Shop around, if you like. After you create an account, you can create a new remote repo called whatever you want. You’ll then be shown a page with some directions. Follow the ones under the heading “Existing Git Repo?”

The git remote add origin git@github.com:<username>/<project>.git command basically tells git where your remote repo is. You can have more than one if you like and, actually, do all sorts of crazy things with naming if you like, but I just want to handle the default, assumed case with this tutorial. One interesting thing: Github gives you two addresses for each repository (other hosts may do the same, I don’t know). The one that starts git@github.com is your read/write address and there’s one that starts git://github.com which is your read-only address. Since this is your own repo, you want to make sure to use the read/write address.

The git push origin master command is what actually moves your commits to the remote repo. This is where I recommend you adhere to the “only stuff that works” doctrine. If this is code, and you’re sharing the repo with your team or whatever, this is where they can get at it, so you don’t want to hand them broken stuff or half-finished ideas or whatever. So only push code that compiles/works. Pushing your code updates the remote repo with all the commits you’ve made since your last push.

The way you (or someone else) gets commits out of a repo is by using git pull. It takes the same arguments as git push. It will pull the commits down and then try to reconcile those changes with any that you’ve made since the last time your local repo was in the same state as the remote repo.

Conclusion/Links

I feel like this has gotten pretty long and I don’t want to put too much information all at once. That should be enough to get you started and, really, just try it out for a while and get comfortable with the basics. Don’t be afraid, if you get something out of whack and realize you’ve done something wrong, to kill your .git directory (which will delete the local repo) and start again from the top. I’ve intentionally left a lot of stuff out (like push/pull and branches and multiple remote repos can get kind of hairy), so here’s some documentation, blog posts and articles that I’ve found helpful. These are in no particular order and some are more advanced than others, so just start clicking and see what you like:

If you want to ask me about git or whatever, feel free to email me or leave something in the comments. Also, if you spot a mistake or something here doesn’t make sense, _please_ let me know. Hope this is helpful to someone.

Version Control Your Computer

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

I’ve mentioned @carl_youngblood here before. Someone once was trying to buy him something with his name on it. I think it was a key chain. You know the kind, right? However, then didn’t have “Carl” only “Carlos”. So we joked that, one day, he needs to write an operating system and name it CarlOS. Aren’t we funny? I know. I’m sorry. Anyway, the other day, we actually got into some OS discussion that I thought had some interesting enough ideas to post here.

So how many computers do you own and use? I’ve got a desktop at home, a laptop and a machine at work. It’s sort of a bummer to have different stuff or different versions of stuff, or stuff with different preferences on different computers. At least, for me it can really jack up my work flow. Especially if there is some application I use a lot with non-default preferences. Man, that bugs me! Remembering it all, bleh.

One thing Carl’s fantasized about is having a computing environment the same everywhere you go. That’s sort of a mainframe or dumb-workstation idea, which is not new at all. However, what if your whole computer were version controlled? You could branch it (so you don’t have your work apps at home, etc.) and merge changes from one branch to another, if you wanted. You could check out a different branch on one machine and it would feel like you were on another.

Clearly an OS would have to be built from the ground up for this idea. You’d also have to have some kind of provision about storing the non-checked out branches locally. Also cloning the repo would be a hassle at current average (even high speed) connection speeds. But how cool would it be to install, say, Textmate at work and get all your settings right, etc. and then go home and merge that change in (You could merge it from work, I guess and then just pull from home. Whatever.)? You could get diff data (hard to implement, but with metadat not impossible):

$os diff gaming HEAD
+ Steam
+ Half-Life 2
+ X-Fire
- Textmate

Or whatever. You get the idea. Reverting would making backing up and creating, uh… what does Windows call them? Recovery Points? It would make all that easy and moot. Clearly Linus Torvalds needs to be in on this “project”; he has the experience in both OS design and version controlling that would be invaluable. Not that, you know, Carl or I are actually considering doing anything with this idea. It’s an interesting thought experiment, though.

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.