Garbled

Social Justice Is Made of Empathy

I was listening to episode 101 of The Ruby Rogues with Ashe Dryden as the guest. The episode includes some of what social justice folks call “101 work”, which is the sort of entry-level explanatory teaching that it takes to get someone from something like “Isn’t a code event specifically for girls, sexist?” to, “That’s not cool”.

Anyway, I really liked the episode, and I recommend you go give it a listen, especially if you’re new or entirely unintroduced to the topic of social justice. They talk a lot about feminism specifically, since there’s been several high profile events related to it this year so far, but they talk about intersectionality, too (like what is is, if you don’t already know).

In this post, I want to address one specific topic they talked about. One sentence, in a way. As part of a discussion about calling people out on comments that are exclusionary or otherwise inappropriate, Ashe was saying that simply saying, “That’s not cool” can have a powerful effect, sending the message that that kind of thing isn’t socially acceptable within the context it was said and that most people will modify their future behavior accordingly.

As a follow-up to that, Avdi Grimm asked if there was ever a time that you’d say something, someone would point out that it made them uncomfortable (or whatever) and you apologized, but decided that whatever the statement was, it was so much a part of who you are, that you knew you’d say it again in the future. I’m paraphrasing, here, hence the lack of quotes. In answer, they talked about a few things, but someone said something else and the conversation kind of got distracted. However, I’d like to address it somewhat.

The flippant answer to the question is, “Of course.” I mean–if I say something like, “I really, really like wearing argyle socks,” and you’re like, “That comment offends me,” there’s not a whole lot I can do for you. Assuming I don’t just think you’re trolling me, I would probably apologize because I don’t like to make people feel bad, but… I seriously wear argyle socks every day. I love that shit. I am likely to express that idea in the future.

But if we’re talking more seriously, thinking of a comment that actually addresses people in some way (instead of socks), I think the idea becomes really interesting (I’ll leave it as an exercise to the reader to come up with an appropriately offensive remark). If you say something offensive or exclusionary, I’m going to give you (and me) the benefit of the doubt an assume it’s because you didn’t realize it would be so. You’re a good person; you don’t enjoy ruining other people’s days.

After making your comment, someone in the group (or near the group over-hearing) says something to you about it being inappropriate and you apologize. Great. How, though, do you get from, “I didn’t realize that was racist,” to “but that thought it so intrinsic to my being that I don’t care and I’ll say it again later”? The only method I can see to get there is if “I am an empathetic human being who cares about others” isn’t a part of how you view yourself.

Personally, I am bad at empathy. I have a hard time reading people sometimes, but I still like to think of myself that I’m empathic. If I manage to figure out that someone was hurt by me, I feel bad. I want to make it better. And in the scenario laid out above, we’re removing that, anyway. Above, I’ve said something and someone flat out told me what was going on, in case I didn’t pick it up.

So if some aspect of that remark is intrinsic to my self image and empathy is intrinsic to my self image, then they’re in competition now. And, I guess, you have to be real with yourself about which one is actually more important to you. Possibly with observation, not introspection. Personally, I’d like my personal narrative to be more about being empathetic to other people than about protecting my ego or whatever.

So, I guess what I’m saying is: If someone near you points out that something you said is out of bounds, and you find yourself saying, “No, my gay friend always jokes around with me that way and he’s not offended,” then you are failing at empathy. At least from the standpoint of someone who is basically sitting on a mountain of privilege (me), social justice isn’t about gay couples wanting to “ruin marriage” or women wanting to invade and displace all our special boys club professions and hobbies or anything like that: It’s about giving a shit about other human beings.

LOL Civil Liberties

The other day, Carol Nichols linked to an interesting article. It is a transcript of a conversation between John Cusack and Jonathan Turley about politics. We traded a few tweets and I said I’d get back to her, but… tweets are short and shit is complicated and, here’s a blog post. I don’t generally talk a lot of politics here, but, screw it. It’s my blog.

So, before I read the piece, Carol was talking about deciding not to vote at all for the Presidency and some stuff about not letting the good things a person has done excuse the lines they’ve crossed. Hopefully I’m not mischaracterizing her statements due to some misunderstanding on my part. In any case, I’d said something in reply about choosing the lesser of two evils (I don’t by any means consider myself a Democrat, but the Republican party is… way off the rails these days). Then Carol said something I hadn’t really considered: If both options have crossed a threshold of minimum-allowable-bad, then choosing the least-bad rather than demanding better enables increasing badness. So I said I’d read the article and get back to her with my thoughts.

Having read the thing (you did, too, right?), I have to say I see what Carol was saying much more clearly. Surprise, surprise. The thing that stood out to me was that I’d heard about Obama’s whole authority-to-assassinate-US-citizens thing when it came out. I heard about it and thought, “That doesn’t sound right.” And… then forgot about it. Or, more accurately, I filed it under “Bad Shit In The World That, Thank Eris, Doesn’t Affect Me” and then got all riled up about health care and tax breaks for the rich at the expense of the rest of us, etc. How did that happen? How did I let that happen? Talking about how the Whitehouse has sold us ideas is true in a sense, but also false in the sense that it can sound like we are actors without agency. They don’t have some kind of mind control over us. I have to accept that I wasn’t really looking at the world as clearly as I’d like or as I’d been telling myself I was.

Some stuff that’s bad in the world and doesn’t affect me, I can live with ignoring (I think this is only pragmatic). But some stuff should go in the other file: Not OK, Damnit. Things like Sexism, Racism, Child Abuse… and The President of the United States deciding he has the authority to unilaterally assassinate people (whether US citizens or not). Ugh. So, OK. I’m upset about that now. And also upset that I wasn’t appropriately upset about it when I first learned of it. That feels like progress.

That issue when paired with the whole unprosecuted war crimes thing and the implications that has for mediating international interactions and Nuremberg precedents really drove Turley’s question home to me: “Morally, are you comfortable with saying, ‘I know the administration is concealing war crimes, but they’re really good on healthcare?’”

And, you know what? That’s a really depressing question to be in a position to even be asked. War crimes are serious shit, you know? They’re the list of things that we’ve agreed we don’t even wish on our enemies. It’s the list of things that super heroes won’t stoop to because “if we do, we’re not better than them.” They are exactly the stuff that we’ve decided the doing of differentiates the Good Guys from the Bad Guys. So if I’m OK with the POTUS doing them, or allowing them to be done or protecting those that did them, then I’m comfortable being a Bad Guy. And fuck that.

So, I guess we’ve established that I feel like there’s a problem and that I’m not happy with either of the candidates put up by the US’s major parties. The next question is: What do I do about it? As part of this discussion, there is the idea that voting makes you implicitly culpable and that if you refrain, you can be said to be calling for better candidates. The culpability angle, I agree with. But I’m also really wary of casting inaction as activism.

I am not an activist by nature; I’ve never been to a rally or demonstration. I’ve never occupied anything except various chairs and sofae mostly in front of video screens. I am also, by nature, physically lazy. So anything that sounds like something I’d do doesn’t seem like it should count as activism. Like changing your Facebook avatar to reflect some fad cause, or writing a ranty blog post about politics (heh). So on that front, I find the “so don’t vote” thing kind of… dissatisfying.

Also, there’s a sort of game theory issue, here. And this may be an illustration of why we’re all just screwed, rather than a justification for an individual’s actions. But this also bugs me: If I was planning on voting for Obama (I was), and now I don’t (undecided, still), then I am letting someone else decide which candidate wins. If I do vote, then I’m at least increasing the chance that the fate I’ve selected is the one I’ll suffer. It feels very Prisoner’s Dilema-ey to me. That’s not an excuse, but it seems to predict that getting a low enough number of people to vote such that the parties notice there’s a reason is infinitesimal.

Of course, on the other hand, not voting is throwing away a resource in a sort of a similar way as voting for a Democratic Presidential candidate in Texas is, so my vote or non-vote is actually pretty unlikely to affect which way my state’s electoral votes go. If I lived somewhere swingey, it would matter more. I guess the decision comes a little more easily, then.

Anyway, I’d love your (thoughtful, respectful) comments and reactions. Especially, I’m interested in help expanding and deepening my thinking about this stuff. I’m sure there’s prior art on some of these ideas that I’m unaware of.

Install Ruby Enterprise Edition With Ruby-build on Arch Linux

I run Arch Linux on a computer, if I have a choice. I recently installed it on the MacBook Air my employer bought me (which saga is another post entirely). One of the things that I like about Arch is that they don’t do big releases every X-period of time; the package repository is updated on a rolling basis. So I can get the latest version of whatever much sooner than my Ubuntuan brethren.

That’s awesome, but also has some costs. One of those costs is that gcc gets updated for me way sooner than it does for people releasing Ruby versions and sometimes there are weird things that older releases of the compiler were more forgiving about or interpreted differently or whatever. So in order to get our app at work that we haven’t yet ported to Ruby 1.9.2 to run, I need to have REE installed. This is how I got it done. This is one of those blog posts that I hope gets indexed so that the next time I have to do this and I ask Google about it, it will show me my own blog post.

Ruby-build

I like rbenv. A lot of people prefer rvm. I don’t want to get into pros and cons or whatever now, but because I use rbenv for managing multiple ruby versions, I use ruby-build to install multiple ruby versions. The way ruby-build works is by executing recipes, which are pretty simple. Here is the one I wrote to handle the install. It’s just a variation on the stock REE install recipe from ruby-build.

ree-1.8.7-2011.12-stdout_patch
1
2
3
4
5
6
7
8
build_package_stdout_patch() {
  wget 'http://bugs.ruby-lang.org/attachments/download/1931/stdout-rouge-fix.patch'
  patch -p1 < stdout-rouge-fix.patch
}

require_gcc
install_package "ruby-enterprise-1.8.7-2011.12" "http://rubyenterpriseedition.googlecode.com/files/ruby-enterprise-1.8.7-2011.12.tar.gz" stdout_patch ree_installer
install_package "rubygems-1.6.2" "http://production.cf.rubygems.org/rubygems/rubygems-1.6.2.tgz" ruby

I won’t get deep into the details, but let’s start with the last 3 lines. Ruby-build executes each of these directives in turn. The first of the three sets up the compiler and the next two each take a series of arguments. The first two of those arguments are what it’s installing and where to get it. Any after that (you’ll have to scroll right) are telling it what to do with it, once it’s downloaded it. It will run the last arguments in the order given. So that brings us to the function I added at the top: build_package_stdout_patch.

When you pass those ending arguments into install package, it will look to execute a function by the name you gave it prepended with build_package_. So the function I wrote downloads a patch for a bug having to do with creating rogue references to STDOUT, then issues the patch command to work it into the REE source. I don’t know a lot about the patch command, so there’s a good chance this could be done more nicely (see below). After that, it runs ruby-build’s standard ree_installer task wich builds and installs the REE source.

Running It

When you’re using ruby-build and rbenv together, you get a nice command called rbenv install. You can either pass it the name of a recipe that ruby-build already knows about or the path to a recipe on your hard drive somewhere. So, in the directory where I had saved my recipe, I ran:

1
$ CONFIGURE_OPTS="--no-tcmalloc" rbenv install ./ree-1.8.7-0211.12-stdout_patch

Note: There’s some kind of problem with tcmalloc and the newest gcc. Or something. I don’t really understand, but since this is just for local development, I decided not to worry too much about performance and skip it. If you set the environment variable CONFIGURE_OPTS, ruby-build will pass those options along in it’s build process. So off it goes to the races. Then, I get this output:

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
Downloading http://rubyenterpriseedition.googlecode.com/files/ruby-enterprise-1.8.7-2011.12.tar.gz...
Installing ruby-enterprise-1.8.7-2011.12...
--2012-02-03 12:07:35--  http://bugs.ruby-lang.org/attachments/download/1931/stdout-rouge-fix.patch
Resolving bugs.ruby-lang.org... 210.251.121.216
Connecting to bugs.ruby-lang.org|210.251.121.216|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 719 [text/x-patch]
Saving to: `stdout-rouge-fix.patch'

100%[======================================================>] 719         --.-K/s   in 0s

2012-02-03 12:07:36 (68.9 MB/s) - `stdout-rouge-fix.patch' saved [719/719]

can't find file to patch at input line 5
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/lib/mkmf.rb b/lib/mkmf.rb
|index c9e738a..7a8004d 100644
|--- a/lib/mkmf.rb
|+++ b/lib/mkmf.rb
--------------------------
File to patch: source/lib/mkmf.rb
patching file source/lib/mkmf.rb
Installed ruby-enterprise-1.8.7-2011.12 to /home/ben/.rbenv/versions/ree-1.8.7-0211.12-stdout_patch
Downloading http://production.cf.rubygems.org/rubygems/rubygems-1.6.2.tgz...
Installing rubygems-1.6.2...
Installed rubygems-1.6.2 to /home/ben/.rbenv/versions/ree-1.8.7-0211.12-stdout_patch

Pay particular attention to the last half of this. After the progress bar, patch gets confused. That’s because the patch is really for Ruby 1.8.7 MRI, not REE. So it complains about not being able to find the file it wants since the projects have slightly different directory structures. You can see where I entered the correct path (basically, I just prepended the source directory). With that information, the patch applies cleanly, it builds REE without tcmalloc and now I have a ruby called ree-1.8.7-0211.12-stdout_patch. Hopefully that’s helpful to someone besides me.

Changems

The other day, I was listening to the Ruby Rogues podcast (which I recommend). The episode was number 36, about Ruby Gems and they had Nick Quaranto on as a guest. For those of you who don’t know, Nick is the originator of the whole GemCutter thing which eventually became what is now RubyGems.org. So he knows a thing or two about gems and, in particular, about the servers that host them all. When you type gem install bundler or whatever, RubyGems.org is where it’s (generally) downloading it from.

I digress. At one point, Nick mentioned that he’d like to see more projects using RubygGems.org’s API and specifically one doing something interesting with gems’ change logs. That, I thought, didn’t sound like a terribly complicated app. So I asked him about it on Twitter, and he pointed me to a GitHub Issue on the topic. You can read the discussion for yourself, but the short of it is that no one was working on a site yet (as best I could tell), so I decided to, and over the 3-day weekend, I banged out Changems.

Right now, there’s fake data in the DB just to give an idea of what I’m thinking. The actual task of getting change logs into the app is not even remotely addressed right now. I’m hoping someone else will at least partially solve that problem, since it’s really hairy. How opinionated do you get? How much freedom do you allow an author before you throw out their log? Should you go so far as to parse Markdown and try to retain code samples and such? Should you only accept plain text (like my fake data) and blow off people who want to get fancy? Then there’s the matter of what people want to call the file (or whether they want to put their change log in the README). Anyway, once those questions at least have rudimentary answers and the site has some real data, I’m sure the community will drive whatever change they feel is appropriate.

Right now, the app is based on the idea that each bullet point in a change log for a version stands alone and is an equal peer with the others from the same version. That might be foolhardy. Maybe each version should just have one big block of data for all the changes; if parsing Markdown or allowing a lot of freedom to make subsections or whatever is important to folks, that would probably be the best bet. But I don’t know yet what folks want. So this post is sort of a plea for help, or at least feedback.

Anyway, it’s 3 evenings of work from one rubyist, so I’m hoping to get people’s thoughts on the topic and maybe some pull requests. If you’d like to talk about it, hit me up on Twitter, or open an Issue on the GitHub repo or, you know, leave a comment here. Also, I threw together the current design, but I am not a designer, so I’d love someone with some actual design chops to send me a pull request. So lemme know: Seem useful? Off to the wrong start? Totally boring? Totally awesome?

The Parameter Object Pattern

I have been paying more attention to software design patterns recently. It all started with my noticing the Null Object pattern and the Ruby Rogues talking about Smalltalk Best Practice Patterns. My most recent discovery is of the Parameter Object pattern. Thanks, by the way, to @timtyrrell for telling me the name of it.

As I’ve mentioned before, I’ve been spending some time at work with a search engine. It works sort of like NewEgg’s search in that you might type a string in (“desktop ram”) and then narrow your search by clicking on links in a side bar (DDR3 or Corsair). The search engine in question powers a product called SubjectLin.es (it’s in beta; you can sign up for a free account to try it out, if you like) where you can search for words that appear in an email subject and then further limit by, say, who sent it (“sender”), what kind of email it is (like coupon or receipt, we call it a “tag”) or what business the sender was in (“market”).

To date, I’ve rewritten the search engine a few times and refactored it a few times. It and one other area of the code base are, by far, the most complex bits of the application, so it has gotten it’s fair share of attention. And it’s gotten more recently when an exception brought our attention to something: We don’t have one search engine… we have four. It’s just that they’re all in one class. Finding the email subjects that a user is interested in is not really related to finding the senders who sent them except that the user’s parameters are the same. So I thought what we’d do is factor out our current search object into 4 smaller ones (subject, sender, tag and market) that each centers around the object it’s pulling out of the DB. Besides code clarity, there are some other benefits we get from this modularity, but I don’t want to get into that in this post.

So now we’re faced with the fact that we’ll have 4 objects we want to create that all depend on the same parameters to build themselves. Add to that the fact that we do some fancy Google-style keyword parsing (you can type “some key words sender:Company” and we pull out the company name) and the fact that if the user is interested in limiting by sender, we want to display things differently than if they aren’t. Now, I thought, it looked as if we should have an object just about the user’s search parameters and that each of our search engines should take only that as an argument.

This way, our view (or presenter… whatever) can ask the search parameter object if the user limited based on sender or not. We can build the one object and then pass it to each of the four engines. We can put all the keyword parsing logic into the search parameter object, too. When I had it, it seemed like such a good idea that it had to have been thought of before. And, lo, it is called the Parameter Object pattern. Or, anyway, I think this is a case of that pattern.

What do you think? Is this Parameter Object? Is it something else? Does my example make any sense at all (I honestly have no idea, since I’m so deep in the system; I tried to balance high-level with need-to-know)? Note: as of this writing, none of this is implemented yet. This is all just design work with @marcosacosta, so far. If anything interesting crops up while we’re writing it, I’ll try to remember to update this post.

A Smarter Has_many :through?

At work, I’ve been expending a lot of effort on this complicated search functionality where you can enter a search phrase that will full-text search over one model’s fields (we’re using texticle [github], which is awesome) and limit the results by which other models are involved relationally. Sort of like searching Amazon for “green converse” and choosing the “shoes” category.

The object graph behind this is pretty complicated and it’s been a real education in SQL trying to make sure the query that gets generated is both reasonably speedy and right. Several times, I’ve gotten it “working” only to realize I was joining in some table more than once and so either returning some record twice or excluding it when I shouldn’t’ve or joining all rows against all rows and, thus, making everything pass all constraints. My SQL skill has leveled up several times throughout, though, which has been really awesome. This is mostly because I was hand-writing a lot of the join SQL with table aliases and whatnot.

Example

The other day, I realized that Rails 3 (or, anyway, the 3.1 release candidates, which is what this app is using) will let you do something that earlier versions would not: do a has_many :through relation on another has_many :through. Say you’ve got Departments composed of Employees. Employees work in groups to create Widgets and which, in turn, get Tags. You can do this number:

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
class Widget < AR::Base
  has_many :tags
  has_many :employees

  has_many :departments, :through => :employees
end

class Tag < AR::Base
  belongs_to :widget

  has_many :employees, :through => :widget
  has_many :departments, :through => :employees
end

class Employee < AR::Base
  belongs_to :widget
  belongs_to :department

  has_many :tags, :through => :widget
end

class Department < AR::Base
  has_many :employees

  has_many :widgets, :through => :employees
  has_many :tags, :through => :widgets
end

Which enables stuff like:

1
Department.joins(:tags).where(:tag => { :id => params[:tag_id] })

The SQL

So, though, since I was hand-writing my JOIN statements before, I’m clearly concerned with what, exactly, it’s going to execute against the database. So I pulled out good ol’ ActiveRecord::Base#to_sql to see. Here’s what I got (edited without all the quoting and with newlines):

1
2
3
4
5
SELECT departments.* FROM departments
INNER JOIN employees ON employees.department_id = departments.id
INNER JOIN widgets ON widgets.id = employees.widget_id
INNER JOIN tags ON tags.widget_id = widgets.id
WHERE tags.id = 3

Hopefully, that query is pretty straight forward and you can see how ActiveRecord has decided how to make all those joins. However, something struck me: I’m joining through with widgets table, but both employees and tags already have widget_id on them. I’d rather have seen something like:

1
2
3
4
SELECT departments.* FROM departments
INNER JOIN employees ON employees.department_id = departments.id
INNER JOIN tags ON tags.widget_id = employees.widget_id
WHERE tags.id = 3

The result set should be the same and it’s slightly faster. In this example, joining through the extra table wouldn’t be a big hit, probably, but if we’ve got more objects all related to Widgets and many are, like Departments, related through some other object, we might be (and in my case often are) joining many more tables, so if we can eliminate middle-man joins, it can have an appreciable effect on the query’s speed.

How We Do It

So it turns out you can make ActiveRecord generate the above SQL. You don’t want has_many :through for the second association. If you do like this:

1
2
3
4
5
6
7
class Department < AR::Base
  has_many :employees

  has_many :widgets, :through => :employees
  # has_many :tags, :through => :widgets
  has_many :tags, :foreign_key => :widget_id, :primary_key => :widget_id
end

You can use the same ActiveRecord query syntax from above to generate the second SQL example. It’s a lot of typing, though, so I wondered: Wouldn’t it be awesome if ActiveRecord knew you when you had this matching-middle-man-foreign-key situation in a query and generated the leaner SQL?

I’m not sure if there are pitfalls to this I’m not seeing (especially related to uses outside what I’m doing with it right now), but I’ve started digging around in the Rails source to see where it’s thinking about these kinds of things (led me to lib/active_record/associations/join_dependency/join_association.rb:72 so far). I’d love some thoughts and feedback on these ideas or guidance in my code-diving efforts. I expect I may end up in the Arel source at some point… we’ll see where it takes me.

Falsiness and Null Objects

Recently, I went to RailsConf. I saw a bunch of talks and met some cool people. This is not a RailsConf post-mortem post (if you’re interested, though, I’ve collected some notes from myself and some others here). This post is about what, in retrospect, was probably the best talk I went to (and I went to several really awesome talks). I’ve been mulling over it since I got back, basically, and that seems like a good result from a talk. That talk was Avdi Grimm’s Confident Code (slides, my notes).

One thing in particular sort of caught at the edge of my thought patterns: The Null Object Pattern. I don’t have a CS degree and so I’m missing a lot of the formal training about design patterns that many programmers have (and, probably, forget), so I’d never heard of it. When Avdi started talking about how ActiveRecord’s try method is a code smell, I was like, “Yes!” I would not say that I hate it, but I have seen several times some line of code that looks like this:

1
@user.try(:posts).try(:recent).try(:first)

I mean… bleh. But I didn’t know a way that looked any better to me, really. Anyway, you can look at the notes and slides to learn about what Avdi says about the Null Object Pattern. I thought it was awesome and so when I went home, I decided to take it for a test drive.

The Test Course

So in a project at work, we have Users and they may or may not have one Subscription. Hopefully, you can picture this complex object graph. Subscriptions may or may not be “current” based on various business rules mostly to do with whether you paid us or not. So, naturally, we have a Subscrption#current? method. But we’re using the User as a sort of presenter for Subscriptions. So you don’t want to call @user.subscription.current?. That’s a code smell. So on User we had this method:

1
2
3
def current?
  subscription.try(:current?)
end

There’s that rascal try. “This,” I thought, “is a perfect spot for that Maybe method from Avdi’s talk.” So I rewrote it thusly:

1
2
3
def current?
  Maybe(subscription).current?
end

W00t, right? Wrong. The accompanying NullObject class looks like this:

1
2
3
4
5
6
7
8
9
class NullObject
  def method_missing(*args, &block)
    self
  end

  def nil?
    true
  end
end

That method missing treatment, so handy in avoiding the chain of trys in my first example, is the gotcha. It means that if I have a User without a Subscription for whatever reason, calling User#current? returns an instance of NullObject, which will pass, say, the boolean clause of an if statement.

So, not sure as to whether I’d misunderstood something, was making some dumb mistake or what, I emailed Avdi. He said, basically, “Awesome question. I will answer it in a blog post.” And, lo, he did. Go read that post to see what he said. The comments also have some good ideas.

Noodles

If you read my comment, I said I was going to noodle on stuff and post again. I had more thoughts than it seemed like would fit in a blog comment. Hence this post. So my initial thought was disappointment. It turned out the Null Object Pattern wasn’t as powerful (in Ruby) as I’d hoped, since if you might have something (calling Maybe) the chances that you’ll have some conditional asking a boolean business-rule question about it is not low.

So I thought about how to get around that. You could, for instance, make a more complex method_missing definition that grepped the message name for /\?$/ and returned false. That’s fail, though. It falls down the moment you have something like this:

1
2
3
if Maybe(@posts).empty?
  # Intuitively, you'd expect NullObject#empty? to have put you in here.
end

But then I realized that Avdi was making a higher-level point: since it is not possible to make your own objects look falsey in Ruby, you have to have another solution. Trying to define various question-mark methods on NullObject is trying to untie the knot, but I should be looking for a way to cut it. So it got me thinking: Why the hell do I have Users without Subscriptions, anyway? Shouldn’t User#current? express that business logic clearly, rather than just express the logic that enforces it? Yes. Yes, it should.

We have some Users who are also admins, who have special rights. It’s also conceivable that we could give away a free account for whatever reason. So, really, we want something like this:

1
2
3
def current?
  self.free_account? || subscription.current?
end

But, this thought it incomplete. It expresses the business logic cleanly: The User is current if they’re flagged as free or if their Subscription is up to date. However, if the weird case of a User who is neither free nor has an associated Subscription crops up, we still have to hunt down the “Undefined method ‘current?’ for nil” error. It sort of has me reaching for Maybe again.

Or maybe (heh, you see what I did there) I want to steal another trick from Avdi’s presentation and have User#subscription return :no_subscription_defined_for_user so that the error message makes some more sense. I don’t like redefining ActiveRecord’s default accessor methods, though, to transparently return the symbol if the real object is missing.

If you’ve got any thoughts, I’d love to hear them.

Release: Twitter_atm 1.0

Holy crap. Did I really start this blog in December 2008? That would make it more than 2 years old. Wow. Well, good on me, I guess. That feels sort of absurd. Anyway…

An Itch…

The other day at work, I had to get the OAuth credentials for a twitter account that our application would use to send programmatic tweets to. For those of you not familiar with OAuth, a brief description: The usual way you OAuth with Twitter is that you have a web page where a user clicks something indicating they’d like to OAuth you to their account. You then send your consumer key and secret off to Twitter to get a request token and, using that, you send the user off to a url over on twitter.com.

Once there, they sign in (or are already signed in) and click “Allow”. Twitter then hits your callback url with some more tokens, which you use to make a final reply and then they respond with the access token and secret you’ll need to do whatever it is you’re doing with the user’s account. If the user changes username or password, you’re still authorized and if they want to revoke your access, they can without changing their username or password. Great! (If you’re thinking, “What?!? Not great! That made no sense!” then maybe the image in this article will help).

However, when your program is a desktop client or when you’ve only got one account you’ll ever be tweeting from (or maybe a small handful), it’s not really practical to build a web interface and a callback url to hit so that you can do the whole dance and get the tokens. So Twitter has an alternate path that replaces the redirects in the middle of the dance. Instead of redirecting users over to twitter.com, you show them the URL and they go there manually. When they click “Allow”, they’re given a PIN, which they then give back to you and you can then finish off the dance as if the PIN were the callback.

…Scratched

So at work, I hacked around in the console for a bit and eventually figured out how to work the PIN-based method, ran it for the account I wanted and then got the access token and secret for our account. But, I thought, I shouldn’t have to hunt all around to figure out how it works (the documentation is almost all focused on the callback path). Heck, if I know my consumer key and secret and I own the account, I shouldn’t need to know how it works at all. So, having figured out how it works already, I decided I’d write a little command to do it for me and publish it as a gem. Thus was born twitter_atm.

The Tool

As the README states, it’s pretty simple. You invoke twitter_atm get_creds with your consumer key and secret as arguments, then it interactively gives you directions on how to finish out the process and spits out the access token and secret at the end. I do want to note, about the name, it’s not about cash. It’s about inputting a PIN and getting something in return. It’s not very exciting to use, so I won’t talk about it much. I’d rather move on to…

An Old God of Asgard

This was the first time I’d written a program with a command line interface, so I asked around a little about gems that were good at that and Jonathan Otto (of Dealzon) pointed me at thor. In short, thor seems awesome. It’s got a nice DSL for describing the various subcommands of your application and it looks deep enough to handle something more complex than my purposes with twitter_atm.

As a brief example, consider git pull --rebase origin master. If you were writing something that would support this syntax in thor, it would look something like this (I made up the git commands inside off the top of my head, so it’s a bit naive):

1
2
3
4
5
6
7
8
9
10
11
12
13
class Git < Thor
  desc "git pull", "Fetches and merges stuff into the current branch."
  method_options :rebase => :boolean
  def pull(remote, branch)
    `git fetch #{remote}`

    if options[:rebase]
      `git rebase #{remote}/#{branch}`
    else
      `git merge #{remote}/#{branch}`
    end
  end
end

You can also declare different types of options, default values, etc. Have a look at the fairly extensive readme and look at how I used it in twitter_atm if that helps. I quite recommend the gem and already have another project I’d like to use it on.

bundle gem twitter_atm

There’s this little project–I don’t know if you’ve heard of it–called bundler. It was started by a couple of up-and-coming young programmers who really might go somewhere some day. Bundler is great for managing gems in a big project and it does this really impressive dependency resolution thing. But there’s a lesser known command that I’ve fallen in love with: bundle gem <gem_name>. It just makes a skeleton for a gem project for you. Unlike Jeweler, it only gives you the bare minimum and really just gets out of your way. You manage your own version number and write your own gemspec (gasp!).

It has three handy rake tasks with obvious functions: rake build, rake install and rake release. Each of those for the most part just issue various gem commands. I basically like it because it builds you a little foundation and then doesn’t really manage anything else for you. One thing that’s important to note: The current version of bundler doesn’t add Gemfile.lock to the .gitignore that it generates (but future versions will), and it is important that you do so. Yehuda has a blog post explaining why.

So, based on this experience, here’s what I took away: Thor is good to use for making a CLI, bundle gem is good to use for making a gem and sometimes you can make something small and cool for yourself in one sitting which gives you a good feeling and is a well invested 5 hours.

Modeling Dominion

Over the past, roughly, 8 months I have gotten into playing a game called Dominion. It’s a card game that is often mistaken for Magic: The Gathering, but in many ways it plays more like some of the more complex board games out there (of which Settlers of Catan may be the most widely known, but not the best example for comparison). In it, there is a pool of common cards which each player may purchase on their turn via a currency mechanic. Cards purchased go into your deck which is drawn from  to make hands and periodically shuffled. It has a bit of the deck-building meta-game of Magic, but in a more primary role and without the annoying, money-sink aspect that collectible card games have. Everyone at the table is drawing from the same central pool of cards, so you can’t spend your way into a better deck between games.

Another aspect that I really like is that the pool of cards for purchase is not the same for each game. You (generally) randomly select 10 types from the box. The initial release had something like 28 types in it. There have been expansions released to add variety, but remember, it’s not a CCG, so buying expansions doesn’t give an advantage to any player over others except, I suppose, that they’ll have greater familiarity with what the cards do. I don’t want to get too into the rules and how the games works. Rio Grande has the rules available as a PDF, so you can go read them in full at the link above. What I really want to talk about is a little hacking exercise that I got into because of the game. Henceforth, I’ll assume you’ve at least read the base rules.

The Discussion

I’ve been playing at lunch with some of the guys at work and I got into a discussion with @hoonpark after one such game. The strategy we were discussing was using Chapel and Treasure Map together. For quick reference, Chapel lets you trash up to 4 (other) cards from your hand and Treasure Map lets you, if you have two in your hand, trash both and then put 4 Golds on top of your deck. The idea was to use the Chapel to reduce your deck size such that the likelihood of getting both your Treasure Maps at the same time went way up and then for most of your deck to just be Golds (with which you would buy Provinces). We disagreed on the exact particulars of how it should be played most optimally and I said, “I bet I could code up a simulator that would play this strategy a ton and give us real statistics.” I think the original debate might have been over whether you try to make two pairs of Treasure Maps work before starting to buy Provinces. At least, that’s what I thought would be best, at first. So I got to work the other evening and coded up the following in two or three sittings. Probably a total of an hour and a half or two.

The Simulation

I have the code up on github, or you can look at this gist. It’s messy as hell and you can tell I sort of just wrote it as I thought of it. I did one refactor, which ended up creating the Player class. That part is probably fairly reusable. The other file could probably be refactored and some bits reused. I want to draw your attention to the commented out lines. I made it so that you can uncomment all the puts statements and run it once to see how just one games goes (which might help you learn to replicate the strategy) or you can run it a bunch and just see a summary. I also ran it several times stopping after buying various numbers of Provinces (3 to 6 ended up being interesting).

As I mentioned above, the original idea was to make Treasure Maps work twice before acquiring Provinces. That ended up taking something like 17 turns on average to get 4 Provinces. When I showed it to Hoon, that didn’t match up with his anecdotal experience, so we looked at the difference between what he’d done (much faster) and what I was seeing. After making it so that the bot would only ever do one pair of Treasure Maps, the turn numbers dropped significantly. Another thing that was different was that Hoon would occasionally buy Silver (if he had less than 5 coins) or, say he drew 2 Golds, 2 Coppers and his Chapel, he would not Chapel the Copper and buy a Province. I think we’ve determined that doing those intuitive things are actually slower than taking the turn to do nothing in the first case or Chapeling the Copper and just buying a Gold.

The Data

The data out of this simulation looks like this (I ran 100,000 games):

  • To acquire 3 Provinces, it takes a minimum of 11 turns, max of 13 and average of 13.93
  • To acquire 4 Provinces, min: 12, max: 14, avg: 13.93
  • To acquire 5 Provinces, min: 15, max: 17, avg: 16.93
  • To acquire 6 Provinces, min: 16, max: 18, avg: 17.93

Notice the gap between 4 and 5. It’s spending those two turns buying Gold , probably. I might, for my own curiosity, run it where it buys Duchies instead, but that could have a slowing effect on the following two turns. Speaking of slowing effects, one thing that I found particularly interesting is that if you don’t ever Chapel Estates away, it dramatically increases turn counts. I set a limit of 100 turns and didn’t count those just as a practicality issue. When running this the published way, I never hit it. When running it without Chapeling Estates, you hit it so often that the simulation took long enough that I got worried and killed it. That’s just 3 krufty cards making a huge difference and really underscores why lean deck strategies are often so powerful.

The Limitations

The biggest limitation of this simulation is that it’s playing in a vacuum. There are no opponents and, more pertinently, no one playing Attack cards (or Masquerade, etc.). If an opponent were to bring Theif to the table, that could be potentially murderous to this strategy. I’m not really sure how the simulation would account for that, anyway. I guess you could figure out tons of strategies, then generate sets of Kingdom Cards and see how they fared against each other in various permutations. That sounds like a) a ton of work for me (or another human), b) a ton of work for some computer somewhere and c) like it might take some of the intuitiveness and gut-checking that I find enjoyable in Dominion. So I don’t think I’ll be chasing that down. I might, however, code up a few other strategies to see how they fare. It would be pretty simple to do a “Just Buy Money” to establish a baseline and a Chapel/Remodel; maybe Village/Smithy, since that’s popular and simple.

How Do You Make a Gem?

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.