|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.|
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'
irb(main):002:0> include OSX
=> "#<nscfarray [#<osx::abwindow:0xb84b8f8="[#<OSX::ABWindow:0xb84b8f8" class="ABWindow" id="0x3bd9f0">, #<osx::nswindow:0xb84b8e4 class="NSWindow" id="0x3d4e00">]>"
irb(main):004:0> NSApp.windows.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.alphaValue = 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.