search
my twitter
subscribe
Saturday
May262012

I hate "you should follow me on Twitter"

Three years ago Dustin Curtis blogged about the conversion rates for different ways he tested of inviting his readers to follow him on Twitter. The phrasing that he found with the highest conversion rate, “you should follow me on Twitter here”, where “here” is a link to his Twitter profile, has since been widely adopted by lots of bloggers; a search for the phrase on Google yields over 700,000 results.

However, the phrase is a complete turn-off for me. I really dislike being told what I “should” do, especially when it’s clearly self-serving on the part of the person that is saying it. If I follow you on Twitter, it’s because I think that you have interesting things to say that I might want to read; it will never be because you told me I “should” do it. Actually, telling me I “should” follow you on Twitter is pretty much a guarantee that I won’t.

I suspect one of the reasons for the high conversion rate in Dustin’s test in 2009 was its novelty. It was new, assertive, and I believe it was always found below one of his well-written and skillfully designed blog posts. Once he posted his findings people soon began to copy it, believing that he had proven that the phrasing would definitely get them more followers. Some people even go so far as to put it in their comment on someone else’s blog. But now that the phrase is in wide circulation, the novelty has worn off and the assertiveness has turned into abrasiveness. Being told by one person that you should follow them on Twitter gets your attention, but when lots of people tell you that it becomes extremely annoying.

As for me, you’ll never see me beg for Twitter followers. If you like what I say and want to follow me, great. If not, that’s fine too. But nobody, least of all me, is in any position to tell you who you “should” follow.

p.s. I know I didn’t provide any actual examples of this phenomenon, but I didn’t want to call anyone out explicitly except the comment that “broke the camel’s back” and provided the impetus for this post.

Saturday
May052012

I'm moving to the Boston area

In September I will turn 25 years old, thus marking the halfway point in my 20s. This fact is bit of a pain point for me, because it shows how fast time passes and makes me think how poorly I’ve made good use of it. I’ve stagnated, personally and professionally, for years, and have little to show for it. With that in mind, my New Years’ resolution this year was to find a professional job in the software development field before my birthday. To that end, I’m happy to report I succeeded: I found a great new job in the Boston area and will be starting in just a few days.

The story of how I got the job, though, requires stepping back a few years to the fall of 2009 when I attended the Stack Overflow DevDays conference in Boston. The conference was interesting (though the chairs were uncomfortable!) and I got the chance to meet some people I had interacted with on Stack Overflow for the past year, as well as meet some new people from the area. One of the people I met and talked with worked for an area company and was hiring new people. I was interested in the idea of getting a job in the software industry, but at the time I wasn’t immediately prepared to move to the Boston area. We ended up following each other on Twitter, but nothing further really came from it.

That is, until about three weeks ago. He posted a message on Twitter saying that he had hired someone, and was looking to hire an additional person for his team. I had been looking for jobs for the previous month or so and even had just had an interview that didn’t work out, so I the tweet couldn’t have come at a better time. I sent him my Stack Overflow CV (something that, given that we met at a Stack Overflow conference, I thankfully didn’t have to explain what it was) and the next day we had a phone interview. The following week I had an on-site interview and was offered a job, which I accepted, on the following day.

Since that time I’ve been involved in the surprisingly complicated details of finding a place to live, as well as tying up loose ends here in Maine. My parents have been extremely supportive thorough this whole process (I think they were just relieved I finally got a good job!). This past Thursday and Friday my father and I looked at the listings for dozens of apartments, called 20-30 of them and visited 6, ranging from a $999 studio to an $1899 one-bedroom place, with a median of around $1400-$1600. There was one that clearly stood out to me as a very desirable place to live, and even though it was pretty expensive I think I made the right decision when I applied for it. I’ll be moving in on May 19th, and my parents are coming down on Memorial Day weekend to help me move some of my larger stuff from my current apartment and to go shopping to help furnish the space with what I need.

I am incredibly grateful to my new employer for taking a chance on me; providing someone with no professional work history and no degree with a very generous offer of employment. I will do everything I can to continually exceed all the expectations they have for me. I’m also grateful for all the help my family has provided in getting me situated in this new job, and I’m really looking forward to starting!

P.S. – If you, the reader, are in the Boston area, and you want to meet up, feel free to send me an email. I’m hoping to meet new people, and if you’re reading my blog then I like you already.

Sunday
Apr222012

A clever Ruby equality trick

Consider the following Ruby class:

class Site
  def initialize(domain)
    @domain = domain
  end
end

A simple class, Site, that is initialized with a value, domain, that is then stored as an instance variable. Suppose we now want to add equality testing. Specifically, we want to establish that two Sites with the same domain are equal. In a language like Java, in the class definition we have access to all the private instance variables, so the solution would look something like:

public boolean equals(Site other)
{
    return domain.equals(other.domain);
}

However, in Ruby, instance methods do not have such access. Private data remains private even among other instances, so the following would not work:

def ==(other)
  @domain == other.domain
end

So how should we go about solving this problem? One approach would be to add domain as a reader on Site:

attr_reader :domain

This would add the necessary method to Site to enable the == method we wrote earlier to work. However, the downside to this is that it makes the private variable public. Let’s assume for this example that we want to keep the domain variable private for some reason. What other alternatives are there?

One solution would be to provide a method that takes the domain as an input and compare that with the locally stored domain:

def domain_equal(domain)
  @domain == domain
end

Our == method can then be constructed using this method:

def ==(other)
  other.domain_equal(@domain)
end

This is better - the value of the domain is no longer directly available, and although passing an object into == that responds to domain_equal would still expose it, this level of protection is sufficient for our purposes.

However, we can still get a bit more clever. Instead of having two methods, we could combine the functionality of domain_equal into == by testing for the class of other. If it’s the same class as domain, we’ve passed in a domain instead of another Site object, so we perform the operation in domain_equal. Otherwise, call the operation as if it were domain_equal:

def ==(other)
  if @domain.class == other.class
    @domain == other
  else
    other.==(@domain)
  end
end

Not bad! Note that in Ruby, other.==(@domain) can be rewritten as other == @domain. Also note that because @domain.class and other.class are equal, and because equality is commutative1 (i.e. a == b is the same as b == a) we can swap the order of @domain and other:

def ==(other)
  if @domain.class == other.class
    other == @domain
  else
    other == @domain
  end
end

Now notice that the bodies of both the if and the else are identical. Therefore, we can remove the test and write == like so:

def ==(other)
  other == @domain
end

Pretty amazing!

This method is deceptively simple - let’s step through how it works. I’m going to use the notation of X.domain to indicate the private variable domain on X:

a = Site.new("google.com")
b = Site.new("google.com")

a == b
 ↳ b == a.domain
    ↳ a.domain == b.domain

When a == b is called, this in turn calls b == a.domain, which in turn calls a.domain == b.domain and performs the desired equality comparison. However, while this trick is clever, it probably should be avoided in actual code because how the method operates may not be obvious to the casual reader.


1 Actually, this whole trick works because equality in Ruby is not commutative - it’s just an instance method on the left operand. However, we can make the switch from other.==(@domain) to other == @domain because the if tests to make sure that the classes of both @domain and other are equal. Since they are, and since we are assuming that equality on instances of those classes is commutative, we can make this swap. Interestingly, even if == is not commutative on the domain class, the operation still preserves the order, meaning that a == b if a.domain == b.domain and b == a if b.domain == a.domain.

Thursday
Mar152012

Sparrow for iPhone review

This morning I wrote and published a review of the new Sparrow for iPhone for the Ask Different Blog.

Conclusion: once they sort out the push notifications, I’m there.

Tuesday
Mar132012

My thoughts on Posterous' acquisition

Yesterday the news broke that Posterous has been acquired by Twitter. Since I doubt Twitter has much interest getting into the blogging space, this is very likely a talent acquisition. Unfortunately, the phrase “talent acquisition” has come to mean shutting down the service within a few months.

In their public statement, Posterous said:

Posterous Spaces will remain up and running without disruption. We’ll give users ample notice if we make any changes to the service. For users who would like to back up their content or move to another service, we’ll share clear instructions for doing so in the coming weeks.

In reading this, it could not be more clear that they intend to shut down the service. The sentence “Posterous Spaces will remain up and running without disruption” is clearly intended only to be true in the immediate term, as the following sentences make reference to giving ample notice and providing a way for users to move their content to another service. This is unfortunate, but to someone that has been paying the least amount of attention to Posterous over the past year, it’s been clear that the company has not been doing well.

First, in January of last year, Garry Tan, one of the two co-founders1left Posterous to join the investment firm that initially invested in Posterous, Y Combinator. While this doesn’t immediately spell disaster, it is worrying when a co-founder quits the company. Second, in the fall of last year, Posterous decided to try to pivot from being a public blog platform to “Posterous Spaces”, which was some sort of private blog/social network hybrid. Presumably this was intended to compete with Tumblr, who had been Posterous’ primary competitor for years and who had developed a rich set of following/liking/reblogging features that Posterous lacked. However, it wasn’t a complete pivot, as users could still create traditional public blogs on the platform.

I never really got Spaces, and I don’t think many other people did. And there was still the problem of how the company would make money - to many people, including myself, Posterous seemed too good to be true, providing a free blog without ads or heavy branding, giving away all the powerful features with no way to directly pay the company. Last fall I was reexamining my decision to choose SquareSpace to host my blog, as well as looking for a place to host multiple blogs for the podcasts I run, and so I was comparing as many services I could find using a variety of criteria. I ended up writing the following summary of my findings of Posterous:

Posterous is in the “seems too good to be true” camp. They get moderate to high marks for everything except the everything-is-a-post category, (also known as the “Tumblr” category). It’s certainly a very compelling site for someone that doesn’t want to pay anything and still get everything. The GA/Feedburner integration is also surprisingly good, and modifying the templates I can add any other JS-based stats app (a la Mint).

With regard to the “too good to be true” thing, my earlier comment2 about “one wonders how they make money” comes into play. Simply put, there are a number of things that could potentially happen:

  • It shuts down due to lack of money
  • It starts to “monetize” in unpleasant ways, either by demanding money or with ads or something
  • Significant changes in how the service operates may be made. They made one such change with the switch to Spaces earlier this year
  • It’s sold to a company that does one or more of the above

So while the Posterous software seems to be pretty close to what I’d need, I’m less bullish on whether the company’s interests are the same as mine.

Sadly, it appears as though I was right, and much sooner than I ever would have thought. It’s unfortunate, too - I have a soft spot for Posterous, as I had used Posterous for my personal blog before SquareSpace, and I was very happy with the software and the service. In fact, some of my content from my Posterous days has made it here. It saddens me to see a service whose failing is not the technology itself, but in failing to find ways to make money with it.

This is why I like SquareSpace. Instead of the company playing around with ways to make money or shutting down and/or selling out when they can’t, SquareSpace just charges their customers to host their sites. That’s it. And although the amount of money I pay per month isn’t large, it’s more than your typical shared hosting account, which means that I know they’re making a healthy profit off each and every customer, thus ensuring that the business will have the means to continue to operate for a long time.

1 There was apparently a third “co-founder”, Brett Gibson, that joined Posterous as a result of an aquisition by the company, but I can’t find much information about him. He’s listed in Crunchbase under the “Former” section, indicating that he, too, is no longer with the company.

2 My “earlier comment” was not included for brevity, but one of the bullet points from above my summary was:
sites are completely free. there appears to be no way to give them any money at all - no premium themes or charging for features. one wonders how they make money