General

Viral software (and in a good way)

I’ve been hanging out with friends in São Paulo over the last few days, getting unreasonably drunk, eating too much and attending the Google Developer Day, not necessarily in that order, so I missed the announcements that Facebook had opened up their API.

As a software developer with a healthy affection for all things related to network effects and emergent behaviours, this is brilliant.

The applications provided get added to a central registry inside Facebook, from where you can pick and choose the ones you want added to your profile. They still have to be deployed separately (as Facebook doesn’t host them for you), but the user doesn’t see any of that - all of it is a very simple and well-designed UI, so “installing” an application to your profile is a hell of a lot easier than installing a desktop application to your machine, and gives the user instant feedback.

Leaving important considerations on data ownership and privacy aside, which I won’t comment on since I haven’t read the agreements in much detail, I can see this thing eating a huge chunk of what we nowadays use disconnected internet applications for. Instant, mobile and email-like messaging, discussion groups, photo sharing and some other basic kinds of applications are already there, as are little data aggregation tools, like the del.icio.us and Magnolia importers. If this API is successful (and so far, nothing suggests otherwise), other social networks could as well be dragged inside Facebook if they support any kind of external API. And, if not, there are always screen scraping tools like Hpricot.

Something to watch out for, definitely. Ten years ago, we were wondering what kinds of applications could be made to run on the internet. Facebook is making us wonder what kinds of applications can be made to run on top of a social network. Which ones would you try?

Geek
General

Comments (1)

Permalink

Thanks, Oracle

We’re using Oracle at my current project. I wanted to run some reporting scripts on the database to do some nice graphs with Graphviz and yEd. “Well, that’s been done before, should be pretty easy to hook up ActiveRecord to Oracle”, I thought.

It turns out that’s nearly impossible to do on an Intel Mac running the x86 version of Ruby, since the Oracle Instant Client SDK only ships with PowerPC binaries so far (hence the title). Unless you recompile your whole Ruby install to PPC, something that to me sits somewhere between unspeakable and atrocious, you can’t link to its libraries, as far as I can tell.

But you can get SQLPlus to run on Rosetta. And you can get SQLPlus to spit out reasonably parseable HTML. And it’ll run slow - but for a quick-n-dirty report that you want to generate once every couple of months or so, it’s… ok.

def select_all(sql)
  html = `echo "#{sql};" | sqlplus -r 3 -l -s -m "html on entmap on" #{@user}/#{@password}@#{@host}`
  doc = Hpricot(html)
  (doc/'tr').collect do |tr| 
    (tr/'td').collect do |td|
      td.innerText.strip if td.innerText 
    end if (tr/'td').size == (doc/'tr/th').collect do |th|
      th.innerText.strip if th.innerText
    end.uniq.size
  end.compact
end

Look what you made me do, Oracle. You should be ashamed. As you can see, though, I’m not that easily embarrassed. Some people wouldn’t ever show this code to anyone, and deny its existence at all possible cost. I think it’s worth the shock value, though. :)

Geek
General
Work

Comments (8)

Permalink

I love the OSA

Inspired by Nat Pryce’s recent scrapheap challenge idea for a Name That Tune style game, and given I’ve been having so much fun with the Ruby OSA lately, I decided to implement my own solution using it to drive iTunes and I had a lot of fun in the process.

I started by grabbing a reference to iTunes:

%w(rubygems rbosa).each {|lib| require lib }

itunes = OSA.app("iTunes")

And then playing about with it until I found the right properties to look at and methods to call. As the game requires a constant stream of random tracks, I thought using the Party Shuffle feature of iTunes to would fit just right. The Party Shuffle is a special playlist that sits inside your library:

library = itunes.sources.find {|s| s.kind == OSA::ITunes::ESRC::LIBRARY }
party_shuffle = library.playlists.find {|p| p.special_kind == OSA::ITunes::ESPK::PARTY_SHUFFLE }

With that party_shuffle (an OSA::ITunes::Playlist object) at hand, it’s pretty easy to do the rest: playing, changing tracks and figuring out how to score each guess.

If you can grab the complete solution and make it into a nice little dashboard widget, I’ll be forever in debt!


BONUS UPDATE: I just finished refactoring a couple of things (namely, moving the monkey patching of OSA::ITunes away - it’s now in itunes.rb) and, in the process of doing so, Tune Fight was born!

Geek
General

Comments (2)

Permalink

How would you improve this page?

On an application I’ve been working during my spare time, I had the need to ask my loyal friends and guinea pigs to give me some feedback, in order to help me fill in the gaps between what I think they want to do and what they really want to do in this application.

A quick, cheap and really useful solution I came up with was adding a feedback form right there, on every page the application renders. This can certainly be improved by people more knowledgeable in Rails than myself, as for now it doesn’t even use AJAX to post the data back (shame, shock and horror!)

After running scaffold_resource Comment body:text uri:string created_by:integer created_at:timestamp, you should be pretty much set to go. Now, on your application.rhtml, you can do something like:

<%= render :partial => "comment", :collection =>
Comment.find_all_by_uri(request.request_uri) %> <% form_for :comment, Comment.new, :url => comments_path do |f| %> <%= f.hidden_field :uri, :value => request.request_uri %> How would you improve this page? <%= f.text_area :body, :rows => 5 %> <%= submit_tag 'Add comment' %> <% end %>

The _comment.rhtml partial is something like this:

<%= comment.body %>
Created by <%= if comment.created_by.nil?
    'unknown'
else
    link_to(comment.created_by.name,
      profile_url(comment.created_by.profile))
end %>

<%= time_ago_in_words comment.created_at %> ago

[<%= link_to 'Destroy', comment_path(comment.id), :method => :delete %>]

Customize the Comment controller slightly, and that’s it — instant feedback forms everywhere! :)

Geek
General
Work

Comments (2)

Permalink

On Socks and Services

Every morning, you have a shower and put some clean socks on. You might still wear the same trousers as the other day, or that t-shirt you wore last friday. Or even an inside-out pair of boxers if you just can’t be bothered. But in the name of all that’s sacred, you need a fresh pair of socks every morning. Don’t dispute this fact.

And there are millions of ways to end up with at least one pair of fresh socks in your drawer, but it’s basically down to either constantly buying new ones, washing them yourself or getting someone else to do it for you, with various degrees of automation.

Suppose, like me, you already tried to buy a 7-pack of socks every week for about two months and realised that was a bad economic decision (and also not a very ecological one), and that you want to dedicate your time at home to learn how to cook that stuff you see on Cooking For Engineers, instead of having to constantly remind yourself to do the laundry. You just don’t want to think too much about it, if at all.

In fact, you want to minimise your involvement in the time it takes to do it, even if the task itself takes a bit longer. The laundrette next door seems like a good idea in this case - your involvement is reduced as now you don’t have to do so many little washes because of the laughable size of the washing machine in your flat.

This would be the equivalent of something like a Web Service. You have to go there, in baskets as big and full as possible as to avoid doing too many trips. You’re subject to environment instability (after all, it’s annoying to walk there in the rain or if the network is playing up) but the economies of scale make it quite cheap. Amazon S3 is a great example.

Then there’s the other laundrette on the high street, which offers pick-up and drop-off. You have even less involvement because now even the question of how your socks get to the service is out of your mind. An equivalent would be a good runtime library - you don’t care how it does it, you just tell it to do stuff, and it works. The environment doesn’t interfere as much, but contrary to the laundrette example, libraries are a lot cheaper to use - in fact, you’ll see in this an inverse relation of cost between the examples.

If you really don’t want to think about the socks, though, you’ll want to hire a maid. A maid will set you back a considerable amount, but your involvement is absolutely zero and your clothes would get washed as soon as they become dirty: a considerably better service. An equivalent would be language runtime features such as a GC, which are almost invisible except when you attend to the fact you’re not doing it yourself.

From there, we can extrapolate:

As software developer-facing services become more elaborate, they require less involvement and cost less to use.

As sock-washing services become more elaborate, they require less involvement and cost more to use.

I imagine we can all quickly understand now why asking your girlfriend to do your laundry is a bad idea, but I’m not sure what’s the software development lesson from all of this.

Geek
General

Comments (5)

Permalink