Author: imccoy

The Slap

by Christos Tsiolkas – I finished reading it last night, and found it quite remarkable. Too many sex scenes, and too many four letter words starting with C, but I was beguiled by the portrait of a family making choices, making bad choices, as everyone does. To have such sympathy for these characters, even as we are presented with the horror of their darkest selves, is striking.

That their humanity was so tied up in the best and worst of themselves was, to me, quite beautiful.

I think maybe the next book I read will be one where some of the characters are not arseholes, though.

heroku db:pull loses foreign keys

So here’s a little rake task to bring them back, assuming that your environment is exactly like mine.

namespace :db do
task :restore_foreign_keys => :environment do
schema = File.open("db/schema.rb").readlines
foreign_key_statements = schema.grep /add_foreign_key/
foreign_key_statements.each do |statement|
ActiveRecord::Base.connection.instance_eval statement
end
end
end

That code is really very ruby. Open the file, read the relevant lines, then.. just eval them in the context of the connection object and hope for the best.

-Iain

Speeding ruby tests up by putting gems on a ramdisk

It doesn’t work.

Time before ramdisk: 32.24 – 33.7 seconds
Time after ramdisk: 32.38 – 33.65 seconds

I am being unfair. The first run without the ramdisk was about 10 seconds slower, then the times were in the range above. With the ramdisk, it went straight into that range. Nevertheless, for the case in which I care most about test runtime, the change-stuff-and-run-again case, as long as the caches stay hot I’m not going to win anything by stuffing around with a ramdisk.

ajax toggle magic

Here’s an obvious-in-retrospect bit of code:


$.fn.liveAndRun = function(event_name, f) {
$(this).live(event_name, f);
f.apply(this);
}

It’s for when you have checkboxes or radio buttons that toggle the visibility of form inputs. If validation fails and you send the form back to the browser, using $(selector).liveAndRun instead of $(selector).live means that the functions that sort out visibility happen on page load, not just when the checkbox gets clicked. And happy unicorns ride ponies to a delicious breakfast.

Time to dance

It’s a train. I find myself on trains pretty often, so that I’m one today is not surprising, what with it being time for me to go home and all. And so I am peering around a sort of empty early evening train, looking for a place to sit, hoping for a forward-facing seat free of litter that isn’t going to be in anyone else’s space.

Yeah, I’m fussy.

Anyway, there’s a young lady sitting near the door I came in through. She’s reading a book but I don’t notice, until after I’d sit down somewhere else, that she moved her bag and made a space next to her. Now I am of course tormented by a question: was she making a space for me? Or did she just think I looked like someone who might grab her bag and start running? Because if the former, by golly, I should go and start a conversation. She turned, and looked at/past/around me, which is just more fuel for my tormented fire. Was that an it’s-okay-you-can-talk-to-me glance, or a you-look-a-bit-suss-I-liked-this-train-much-better-without-you glance? (Or, as is frankly more likely, an is-it-just-this-half-of-the-train-that’s-empty? glance). I looked back at her, hoping to get a hint from these choreographed glances, and then a surprising thing happened.

She got up and moved from her seat to one adjacent to mine. Now, the probability that she’s inviting a conversation just shot waaaay up. I never know if it’s creepy to start a conversation with a girl on a train or not; but if there are times when it’s not, this is one of them. I start turning words over and around in my mind, trying to find a suitable way to start the conversation, a way that will let her opt out of the conversation easily but interest her enough that she won’t want to. Finally the words lined up, and I prepared to attempt to start the conversation.

Then she moved to the end of the train.

Rails respond_with customize conversion

Rails 3 introduces some cute stuff so that you can say respond_with(thing), and it will convert that to a json or xml representation if required. But how do you alter that, if (for instance) you want the to_json call to only use certain fields on the model?

You change this:

    respond_with(thing)

To this

    respond_with(thing, :only => [:name])

Arguments that you pass after the object in the respond_with call get passed through to the to_json method, you see. And arguments you lose stay lost forever.

Android and clojure, 2 apks and a proxy

(Edited to add: see the triumphant conclusion)

I mentioned this possible approach near the end of the last episode. This one hasn’t worked for me yet. I wrote a little activity, which tries to load a clojure .apk, then offers that .apk as a parent classloader to load my actual stuff from another apk. This starts well, in that my actual stuff gets access to the clojure libraries. But it goes wrong, because one of the first things it tries to do with those clojure libraries is load another class. But that class is in the “wrong” APK, and it falls over.

Here’s the structure. If you have a reference to something lower down the stack, you can pull it out specifically – so in A, I can get something from C – but by default you just get stuff from higher up the stack:

A – an activity in java
B – the clojure runtime
C – my activity in clojure

And what happens is that I load my activity from C, it hits up the clojure runtime, the clojure runtime starts looking for another part of my activity, but it looks up, not down, so it never finds it. I hoped to get around this by tweaking the clojure runtime to look to the thread’s contextClassLoader for all it’s class loading needs, then shoving classloader C in the diagram above in as the contextClassLoader before loading stuff from it, but no love from that one.

This is getting silly. I wanted to make a triumphant post telling of a beautiful and awesome approach that you could use to make this practical. Not there yet.

On the other hand, the build for this package is nice and fast. The compile+install only takes 7 seconds. But let’s not talk about the 30 second app startup time.

Evening

It is nighttime. The temperature: mild. The hour: late. My mood: glum. Steering my mind gently to a spot beside sadness, I open myself to the beauty of the world around me. The sound of distant traffic, the feeling of the breeze upon my face, the sudden crunch of a twig underfoot.

Good friends, lazy evenings. The bag on my back and the way I’m holding my shoulders. The placement of every step and the position of my tongue in my mouth and how open my eyes are. And then, a sudden realization: I didn’t know my undies chafed.

Android and Clojure, but faster. Almost.

I have an ongoing interest in getting functional languages to be happy fun times on mobile devices, the first target of which is android and clojure. I mentioned there that there are some ideas around getting the DEX stage faster, and now I’ve spent some time chasing them up.

The problem:

The DEX stage takes somewhat over one minute for the clojure runtime. The current arrangement of clojure stuffs takes about 90 seconds to build up and install a complete artifact including that; if we don’t dex the clojure runtime, then the time to build up and install drops down to more like 10 seconds.

DEX wha?

Android is java, almost. The VM on the device is a Dalvik VM, not a Java VM, and it understands Dalvik bytecode. I believe this is a strategy for doing space-efficient VMs without treading on Oracle’s (nee Sun) patent toes, but whatever the motivation, you do need to send Dalvik bytecode to the device. The DEX stage takes Java bytecode as input and produces Dalvik bytecode.

There’s an obvious solution, right?

Yep! instead of converting the clojure runtime to dalvik every time we build, let’s just convert it once, then include the converted stuff every time we build up a package.

So what’s in that github repo linked by the mailing list thread?

It makes Clojure android-aware. If Clojure is running on android, then with the patches:

  • the writeClassFile method will also dex the resulting class file and pack it into a .apk
  • when it needs to look up a class file for an ObjExpr, it will do so by loading up the relevant .apk file with the DexClassLoader
  • when trying to load a file, it looks – if on android – for a .apk file and throws it to the DexClassLoader

So you just use that, right?

Um, no. It checks if it’s running on android, and acts differently if so. I want to compile stuff up on the desktop and send it down to the device.

So you just use some part of that, right?

Well, in theory. I hacked it up so that on the desktop it will dex up all of the android classes, and included them into my app along with clojure’s RT.class so that the magical loading function is available to get clojure libs out of dex files. Then I used the same compiler to build up my app. I haven’t been able to get it to work, though – it turns out that getting the magical loading function to work is rather tricky.

I thought that sounded like overkill, though: it should be enough to build up clojure, dex clojure.jar, shove the resulting .dex file into a .apk, and stick that .apk file into your applications’ .apk. Then all you need to do is stick a class loader in so that the VM loads up your clojure apk before it tries to load up your activities and such. Turns out that doesn’t work either, because the VM will use the ClassLoader that it used to load your class, to load any classes that your class references. My activity class is defined in my applications’ apk, but being written in clojure needs some stuff from the clojure apk. By the time android has started up my activity, it’s too late for me to hook the classloaders up the way I want.

So what do you do, then?

There are three options I am still exploring, one of which is suggested by MHOO’s approach. Clojure has an internal hook for loading the .class file corresponding to a method, and it’s possible to hack that hook up so that it looks to a .apk instead (this is the third point above). As long as everything in the Activity’s class goes through that hook to get its clojure machinery, that should work.

But that’s clojure-specific..

There are two more general strategies I’m considering.

  1. Translate the language’s .jar to .dex. Keep that file around. Instead of re-dexing it each time, augment the language’s jar with the application’s dexed stuffity stuff. I don’t know enough about the dex format to say if this will actually be any faster than dexing the language and application every time.
  2. Compile your language to a jar. Dex that jar. Compile your application to a jar. Dex that jar. Then have a handful of bootstrap classes at the top level which load the language .apk, use that classloader as the parent classloader to load your application .apk, and implements proxies to all of the Activities, Services &c in your application.

And there’s a third option: live with the slow build time.

Hopefully I will – at some point – follow this up with a post containing an actual solution :)

Mechanize, capybara and a http proxy

We had trouble at work today with getting mechanize – via the capybara-mechanize driver – to go over a http proxy. And thus this little snippet of code was born:

  proxy = URI.parse(ENV['http_proxy'])
  Capybara.current_session.driver.agent.set_proxy(proxy.host, proxy.port)

It worked for us.