Hi Mike,

On May 26, 2009, at 5:45 PM, Mike Laurence wrote:

Hello,

I'm trying to get some obj-c code to talk back to my ruby. After
encountering some "EXC_BAD_ACCESS" messages and scouring the web, I've
concluded that I'm probably supposed to use performRubySelector
instead of just expecting selectors to work when overridden by ruby
subclasses, etc.

What is the preferred way to get this to work? I looked through some
of Elysium's old code (which used performRubySelector), but I'm having
trouble wrapping my head around how you're supposed to use the MacRuby
sharedRuntime to get things to happen. If someone could give me a
quick example of how to call arbitrary ruby methods, I would highly
appreciate it.

Of course, if I'm completely off base and there's some other way to
call ruby code, please let me know!

Calling Ruby from Objective-C can be problematic, depending if you want to call a pure Ruby method or a Ruby method that overrides an Objective-C one. If you want to dispatch the method by yourself (and if it's a Ruby method that overrides a specialized Objective-C method), you may want to be very careful about the types of the arguments you are passing to, as well as the return value.

In any case, using performRubySelector: is better because arguments will be converted from Objective-C objects (id) into the expected type, and the return value will be converted into an Objective-C object. Also, performRubySelector: can deal with Ruby methods that have optional or splat arguments.

$ cat t.m
#import <Foundation/Foundation.h>
#import <MacRuby/MacRuby.h>

@interface Foo : NSObject
@end

@implementation Foo
- (int)aMethodReturningInt
{
    return 123;
}
@end

int main(void)
{
[[MacRuby sharedRuntime] evaluateString:@"class X; def foo(x=1, *a); p x, a; end; end"];
    Class k = NSClassFromString(@"X");
    id o = [k new];

    [o performRubySelector:@selector(foo)];
    [o performRubySelector:@selector(foo:) withArguments:@"1", NULL];
[o performRubySelector:@selector(foo:) withArguments:@"1", @"2", @"3", NULL];

[[MacRuby sharedRuntime] evaluateString:@"class Bar < Foo; def aMethodReturningInt; 42; end; end"];
    k = NSClassFromString(@"Bar");
    o = [k new];

    NSLog(@"%d", [(Foo *)o aMethodReturningInt]);
NSLog(@"%@", [o performRubySelector:@selector(aMethodReturningInt)]);

    return 0;
}
$ gcc t.m -o t -framework Foundation -framework MacRuby -fobjc-gc
$ ./t
1
[]
"1"
[]
"1"
["2", "3"]
2009-05-27 18:16:36.092 t[11922:10b] 42
2009-05-27 18:16:36.095 t[11922:10b] 42
$

If you still have problems, it would be easier if you could paste some code, this way I can try to help you more.

HTH,
Laurent
_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to