[MacRuby-devel] How to create loadable MacRuby bundle

Laurent Sansonetti lsansonetti at apple.com
Tue Oct 14 14:34:31 PDT 2008

Hi Antonin,

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  
> support.

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 mailing list