Embedding MacRuby
While writing portions of mac programs in Ruby and mixing it with Objective-C is cool, but it's not all that MacRuby could do. I'm attempting to write an application which would contain scriptable parts, utilizing MacRuby (Lua has been used for this purpose for a long time, but MacRuby with access to ObjC classes is a much more powerful tool for the job!). So far I've run into these issues, any help appreciated: - Need to execute MacRuby code from any source (parse a string) Solution 1: "rb_eval_string" - does not cut it because of a bug (#109 in trac) - it seems MacRuby forgets variables created by previous calls to rb_eval_string, maybe there's more to it then that Solution 2: [RBKernel eval:@"..."] - This example has been mentioned in this mailist but I've found no references to RBKernel or anything similar in the MacRuby.framework. Guess it was more of a proposal. - Need to be able to clean up (full reset) of the MacRuby VM - release all defined objects, undefine classes. Is this even possible? How costly would it be, time-wise? Yuriy Makhin
Hi Rakoth, On Aug 19, 2008, at 7:21 AM, Rakoth Lichlord wrote:
While writing portions of mac programs in Ruby and mixing it with Objective-C is cool, but it's not all that MacRuby could do.
I'm attempting to write an application which would contain scriptable parts, utilizing MacRuby (Lua has been used for this purpose for a long time, but MacRuby with access to ObjC classes is a much more powerful tool for the job!).
Thanks :)
So far I've run into these issues, any help appreciated:
- Need to execute MacRuby code from any source (parse a string) Solution 1: "rb_eval_string" - does not cut it because of a bug (#109 in trac) - it seems MacRuby forgets variables created by previous calls to rb_eval_string, maybe there's more to it then that Solution 2: [RBKernel eval:@"..."] - This example has been mentioned in this mailist but I've found no references to RBKernel or anything similar in the MacRuby.framework. Guess it was more of a proposal.
I would like to introduce an Objective-C API in MacRuby core to permit this kind of things from a pure Objective-C environment. Basically initializing the VM, evaluating expressions, but also creating blocks, etc... Right now, one thing you can do is to mimic what macruby_main() does, to initialize the VM. Then, in theory, rb_eval_string() should just work. You could also try to call Kernel#eval directly: (gdb) po [rb_mKernel eval:@"1+1"] 2 Here rb_mKernel is a static variable that points to the Kernel module, but you can also retrieve it dynamically. (gdb) po [objc_getClass("Kernel") eval:@"1+1"] 2
- Need to be able to clean up (full reset) of the MacRuby VM - release all defined objects, undefine classes. Is this even possible? How costly would it be, time-wise?
I don't think this is possible, right now. But we can work on this. At a glance, the only problematic thing would be to remove C extensions that were loaded. Laurent
- Need to be able to clean up (full reset) of the MacRuby VM - release all defined objects, undefine classes. Is this even possible? How costly would it be, time-wise?
I don't think this is possible, right now. But we can work on this.
Tearing down the old classes would be really difficult, since they might be referenced by objects that have been passed to the Obj-C side. I suppose if you used unique Objective-C class names and just cleared the Ruby->ObjC map, it wouldn’t be as bad, but then you need extra shenanigans to use Ruby classes from Objective-C.
At a glance, the only problematic thing would be to remove C extensions that were loaded.
dyld can do this in Leopard. Hooray. -Ben
On Aug 19, 2008, at 12:55 PM, Benjamin Stiglitz wrote:
- Need to be able to clean up (full reset) of the MacRuby VM - release all defined objects, undefine classes. Is this even possible? How costly would it be, time-wise?
I don't think this is possible, right now. But we can work on this.
Tearing down the old classes would be really difficult, since they might be referenced by objects that have been passed to the Obj-C side. I suppose if you used unique Objective-C class names and just cleared the Ruby->ObjC map, it wouldn’t be as bad, but then you need extra shenanigans to use Ruby classes from Objective-C.
In fact, in my private branch (to be merged in trunk very soon), the Ruby classes semantics are now fully implemented in Objective-C classes (so there is no such thing as a Ruby class anymore). I still keep a map of classes that were created by Ruby, so it would just be a matter of removing them from the runtime and cleaning the hash. Obviously, if there is still a reference to them in the Objective-C side, it's not going to be nice (AFAIK classes are not allocated from the autozone). This feature would have to be used very carefully.
At a glance, the only problematic thing would be to remove C extensions that were loaded.
dyld can do this in Leopard. Hooray.
Oh nice, I will look at this :) Laurent
Obviously, if there is still a reference to them in the Objective-C side, it's not going to be nice (AFAIK classes are not allocated from the autozone). This feature would have to be used very carefully.
Actually, I just remembered that the dyld unload support includes unloading Obj-C bundles. If it can do that then there must be a way to tear down the classes, too. I’ll try to make time to dig into the runtime to see what they do when this happens. -Ben
participants (3)
-
Benjamin Stiglitz
-
Laurent Sansonetti
-
Rakoth Lichlord