Continuing adventures in macruby

I was puttering around in an attempt to clean up my mess of ruby omnifocus-organisation scripts today1 (using macruby) when I hit a bump:

1
2
3
4
5
6
7
8
#!/usr/bin/env macruby

framework "ScriptingBridge"
of = SBApplication.applicationWithBundleIdentifier("com.omnigroup.omnifocus").defaultDocument
predicate = NSPredicate.predicateWithFormat("completed = YES")
of.flattenedTasks.filterUsingPredicate(predicate).each do |task|
  # More code here...
end

Run this, and you get something like the following:

1
2
3
4
2013-04-14 19:43:09.235 macruby[88194:60b] -[SBObject classForCode:]: unrecognized selector sent to instance 0x400189ce0
uncaught Objective-C/C++ exception...
2013-04-14 19:43:09.237 macruby[88194:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SBObject classForCode:]: unrecognized selector sent to instance 0x400189ce0'
*** First throw call stack...

This is somewhat annoying, but I’d encountered it before. As far as I can work out, macruby lazily evaluates these sort of filters when they’re needed, and calling #each on the search doesn’t evaluate it. If I had to guess, I’d say it was a communication breakdown between macruby and cocoa. There is a simple solution, however:

1
2
3
of.flattenedTasks.filterUsingPredicate(predicate).allObjects.get.each do |task|
  # More code here...
end

This effectively gets all the objects for you, like you’d expect.


  1. It’s like gardening, only with less concrete outcome and I can’t really tell my parents anything about it.