[MacRuby-devel] How to create loadable MacRuby bundle
lsansonetti at apple.com
Tue Oct 14 14:34:31 PDT 2008
On Oct 13, 2008, at 11:08 PM, Antonin Hildebrand wrote:
> Hi Laurent,
> I'm porting my app from RubyCocoa to MacRuby. I wanted to implement
> simple plugin system for this app..
> Plugins contain not only ruby scripts, but also nib files (and maybe
> other resource stuff).
> I'm quite new to Mac development, so I may be totally wrong. My
> approach was to create every plugin as a RubyCocoa loadable bundle.
> In RubyCocoa during application startup I load all plugins using
> NSBundle.bundleWithPath(path).load and it correctly does two things:
> 1. initializes nib machinery
> 2. calls my ruby script, in which I hook into main application (it
> gives me the same ruby environment as has main application)
> In ideal case I don't want limit plugin developers to use MacRuby,
> RubyCocoa or any other particular technology.
> I want them just to create loadable bundle and use my application
> hooks in their init call (hooks should be accessible from their
> environment somehow).
> I can imagine to write ruby C-extension inside my main application to
> bridge ruby methods into C and present hooks to plugins as plain C API
> (which everybody should understand).
> If this is too complicated, I can live with just MacRuby bundle
In this case I would then recommend the bundle idea, since plugins
might ship with non source-code files such as nibs or resources.
If you want to make your plugin system agnostic from the language it's
implemented in, I guess the best way would be to use C or Objective-C
to implement the "hook" that would be called after the bundle is
loaded from the the app.
Then, one could implement a plugin in pure C or Objective-C simply by
implementing the hook method. And if one wants to implement it in
MacRuby, it would just be a matter of implementing the hook method in
C/Objective-C and do the following:
NSString *pathToTheRubyScript = ... // look for the full path of
your ruby script inside the plugin bundle
[[MacRuby sharedRuntime] evaluateFileAtPath:pathToTheRubyScript];
The sharedRuntime method will initialize MacRuby if needed, in your
case since your app is written in MacRuby it will do nothing. Then the
file will be evaluated. The full API is available when you `#import
<MacRuby/MacRuby.h>` and here is the latest version of the header file:
One thing to take into account is that plugins will have to be
compiled with the -fobjc-gc option, because MacRuby uses the Objective-
C GC and therefore dyld will check if all dynamic libraries support
the GC before loading them.
More information about the MacRuby-devel