Log in

Dec. 30th, 2007 @ 07:26 am rubyinject: nutty!
With rubyinject you can attach a ruby interpreter to any running application and send it messages. Because of the huge dynamism of the objective-c runtime, it means you can modify running applications in dramatic ways - applications whose source you've never seen.

Trivial examples:

jon:~ paulp$ ps? address
paulp 84385 0.1 0.4 446888 16600 ?? U 7:11AM 0:00.54 /Applications/Address Book.app/Contents/MacOS/Address Book -psn_0_3220242
jon:~ paulp$ sudo inject.rb 84385

irb(main):001:0> require 'osx/cocoa'
=> "true"
irb(main):002:0> include OSX
=> "Object"
irb(main):003:0> NSApp.windows
=> "#<nscfarray [#<osx::abwindow:0xb84b8f8="[#<OSX::ABWindow:0xb84b8f8" class="ABWindow" id="0x3bd9f0">, #<osx::nswindow:0xb84b8e4 class="NSWindow" id="0x3d4e00">]>"
irb(main):004:0> NSApp.windows[0].title = "Funky Chicken"

And sure enough, the title bar on the address book changes as ordered. Let's make it almost transparent:

irb(main):006:0> NSApp.windows[0].alphaValue = 0.2
=> "0.2"

I can see right through you!

The injection capability isn't new (f-script anywhere has been around for a while, and you always use objective-c) but there must be a hundred times as many ruby programmers as f-script programmers, and the whole process seems to be getting less hacky over time as apple improves its support for languages that aren't objective-c. The prospect of fixing major annoyances in cocoa applications with a few lines of ruby is pretty awesome. Think firefox extensions, but for everything. Need a good distribution mechanism though - there's nothing I hate more than downloading little bits of code from here and there.
About this Entry