Hi Victor,
On Apr 16, 2009, at 4:23 AM, macruby-de...@principia.info wrote:
Hi,
I'm new both to this list and to MacRuby. Let this message serve as
an introduction.
I have some questions that have not seen answered either in the
docs or in the list archives. I have been known to miss things
before, so please kindly point me in the right direction if this is
documented somewhere.
I have seen the embedding sample but I stil can't figure out how I
can pull out the following:
1. Mix Obj-C and Ruby Classes: ie, from Ruby be able to extend or
use Obj-C classes that are lying around in my project. How do I
"require" them? When I try to use them, ruby doesn't seem to
recognize them (specifically, it recognizes the classes but not
their methods)
Normally MacRuby will recognize your Objective-C classes and their
methods. If you see the classes from Ruby but not the methods it may
be a problem in the way you use MacRuby (or a bug in MacRuby).
Also, keep in mind that calling #methods on an object in Ruby won't
show the Objective-C selectors, you need to pass the second parameter
as true to show them (this is to keep compatibility with Ruby).
$ cat hello.m
#import <Foundation/Foundation.h>
@interface Foo : NSObject
@end
@implementation Foo
- (void)sayHello:(id)sender
{
NSLog(@"hey %...@!", sender);
}
@end
// We declare an Init_ method so that we can load this extension from
MacRuby
// using #require.
void Init_hello(void) {}
$ gcc hello.m -o hello.bundle -g -framework Foundation -dynamiclib -
fobjc-gc -arch i386 -arch x86_64
$ macruby -e "require 'hello'; Foo.new.sayHello('MacRuby')"
2009-04-17 22:44:49.495 macruby[67329:10b] hey MacRuby!
2. The same question, but the other way around: how can I use or
extend a class declared in Ruby from Obj-C? The only thing that I
can come up with is to declare them with @class, but it didn't work
(or I didn't do it properly)
This is also possible, but it requires some runtime calls since
Objective-C is more static than Ruby (the problem is that Objective-C
declares classes at compilation time but Ruby does it at runtime).
Here is a dirty way to do this (note that it uses a deprecated API in
the runtime). Another cleaner way would be to subclass the Ruby class
dynamically too, by creating the class programmatically right after
loading the Ruby expression.
$ cat hello2.m #import <Foundation/Foundation.h>
#import <MacRuby/MacRuby.h>
@interface NSObject (FooInterface)
- (id)foo;
@end
@interface ObjCFoo : NSObject
@end
@implementation ObjCFoo
- (id)foo
{
NSLog(@"objc_foo");
[super foo];
}
@end
int main(void)
{
[[MacRuby sharedRuntime] evaluateString:@"class Foo; def foo;
p :ruby_foo; end; end"];
Class k = NSClassFromString(@"ObjCFoo");
class_setSuperclass(k, NSClassFromString(@"Foo"));
ObjCFoo *o = [[ObjCFoo alloc] init];
[o foo];
return 0;
}
$ gcc hello2.m -o hello2 -framework Foundation -framework MacRuby -
fobjc-gc -arch i386 -arch x86_64
hello2.m: In function ‘main’:
hello2.m:25: warning: ‘class_setSuperclass’ is deprecated (declared
at /usr/include/objc/runtime.h:126)
hello2.m:25: warning: ‘class_setSuperclass’ is unavailable (declared
at /usr/include/objc/runtime.h:126)
hello2.m: In function ‘main’:
hello2.m:25: warning: ‘class_setSuperclass’ is deprecated (declared
at /usr/include/objc/runtime.h:126)
$ ./hello22009-04-17 22:53:55.596 hello2[67436:10b] objc_foo
:ruby_foo
3. If I were to call arbitrary scripts as in the embedding sample,
how can I pre-initialize ruby objects so that they are available in
the environment? I.e, if I allow the user to extend my app by
running their ruby code, how can I make my objects available to him?
And also, how could I prevent certain objects from being available
to him, so that he doesn't break anything?
Once you link against MacRuby and call the -[sharedRuntime] method,
all Ruby classes should be available in Objective-C. Ruby objects
created from Objective-C must be referenced by Objective-C otherwise
the garbage collector will free them. It is up to the developer to
manage the Ruby objects created from Objective-C.
Vice-versa, Objective-C classes & objects are available in Ruby. There
is no way to hide classes/objects, everything is dynamic.
HTH,
Laurent
_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel