Accessing Obj-C InstVars from Ruby
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension? I'm porting some of Apple's example code to MacRuby as a learning experience and would like to do so incrementally. Porting the code one class at a time works fine, but for some of the larger classes I'd like to port them a few methods at a time. Here's an example of what's happening --- Example.h --- @interface Example : NSObject { NSString *instVarA; NSString *instVarB; } - (NSString *)methodA; @end --- Example.m --- #import "Example.h" @implementation Example - (id)init { if (self = [super init]) { instVarA = @"instVarA"; instVarB = @"instVarB"; } return self; } - (NSString *)methodA { return instVarA; } @end --- Example.rb --- class Example def methodB @instVarB end end Then at runtime, when I execute the following... example = Example.alloc.init puts example.methodA.inspect puts example.methodB.inspect .. I get "instVarA" nil How do I access InsVarB from Ruby? Thanks, Ed
Hello Edward, well since no one else has answered i will speculate a bit (it might provoke someone wiser). I assume that the Ruby and the Objective C class are magically married together perhaps via some sort of proxy class - since you cant as far as i know add to an objective C class more instance methods - and inserting a compiled class into a ruby class must be also problematic - anyway it seems complicated. So I assume that the ruby class is actually still a separate class. I must admit i never tried to extend a compiled object C class - and I surprised it works as well as it does. Given that, what about just adding getters and setters in the usual way to the objective class manually or with properties (see http://theocacao.com/document.page/510)? Or just rewrite the whole class in Ruby? Cheers, J On 3/30/09, Edward Hynes <ehynes@dharmagaia.com> wrote:
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension? I'm porting some of Apple's example code to MacRuby as a learning experience and would like to do so incrementally. Porting the code one class at a time works fine, but for some of the larger classes I'd like to port them a few methods at a time. Here's an example of what's happening
--- Example.h ---
@interface Example : NSObject { NSString *instVarA; NSString *instVarB; }
- (NSString *)methodA; @end
--- Example.m ---
#import "Example.h"
@implementation Example - (id)init { if (self = [super init]) { instVarA = @"instVarA"; instVarB = @"instVarB"; } return self; }
- (NSString *)methodA { return instVarA; }
@end
--- Example.rb ---
class Example def methodB @instVarB end end
Then at runtime, when I execute the following...
example = Example.alloc.init puts example.methodA.inspect puts example.methodB.inspect
.. I get
"instVarA" nil
How do I access InsVarB from Ruby?
Thanks, Ed
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
Hi John & Edward, On Mar 30, 2009, at 11:27 AM, John Shea wrote:
Hello Edward,
well since no one else has answered i will speculate a bit (it might provoke someone wiser).
I assume that the Ruby and the Objective C class are magically married together perhaps via some sort of proxy class - since you cant as far as i know add to an objective C class more instance methods - and inserting a compiled class into a ruby class must be also problematic - anyway it seems complicated. So I assume that the ruby class is actually still a separate class. I must admit i never tried to extend a compiled object C class - and I surprised it works as well as it does.
In MacRuby, a Ruby class is a true Objective-C class. We try to use the Objective-C runtime for everything possible, however, because of some limitations of Objective-C there are things we need to do on the side, like for example maintaining instance variables (in Objective-C you cannot add an instance variable dynamically to a class).
On 3/30/09, Edward Hynes <ehynes@dharmagaia.com> wrote:
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension?
It is currently not implemented, but it's technically possible. A good work-around is to define accessors (properties) as John mentioned. Laurent
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension?
It is currently not implemented, but it's technically possible. A good work-around is to define accessors (properties) as John mentioned.
Maybe we need MacRuby::Runtime to bubble up the Obj-C runtime. Or FFI. -Ben
On Apr 1, 2009, at 8:07 AM, Benjamin Stiglitz wrote:
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension?
It is currently not implemented, but it's technically possible. A good work-around is to define accessors (properties) as John mentioned.
Maybe we need MacRuby::Runtime to bubble up the Obj-C runtime. Or FFI.
Might be a nice feature, but in this case I think we should simply expose the existing Objective-C ivars in variable.c, by adding another lookup path. If someone is willing to investigate that let me know. Should not be that hard. Laurent
I started working on this. I have a failing test case and figured a way to hook in the objc lookup inside the ivar_get function. However, I haven't figured out how I can call object_getInstanceVariable with an ROBJECT.. any hints appreciated. Regards, Mathias On 3 Apr 2009, at 19:29, Laurent Sansonetti wrote:
On Apr 1, 2009, at 8:07 AM, Benjamin Stiglitz wrote:
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension?
It is currently not implemented, but it's technically possible. A good work-around is to define accessors (properties) as John mentioned.
Maybe we need MacRuby::Runtime to bubble up the Obj-C runtime. Or FFI.
Might be a nice feature, but in this case I think we should simply expose the existing Objective-C ivars in variable.c, by adding another lookup path. If someone is willing to investigate that let me know. Should not be that hard.
Laurent _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
Hi Mathias, On Apr 4, 2009, at 7:49 PM, Mathias Sulser wrote:
I started working on this. I have a failing test case and figured a way to hook in the objc lookup inside the ivar_get function. However, I haven't figured out how I can call object_getInstanceVariable with an ROBJECT.. any hints appreciated.
Very cool! You can simply cast the object as an `id'. In MacRuby, all objects except immediates [1] are Objective-C objects and can be casted as `id'. Laurent [1]: fixnums, true, false, nil, Qundef (not exported) - in your case these should already be caught earlier in ivar_get/set.
Regards, Mathias
On 3 Apr 2009, at 19:29, Laurent Sansonetti wrote:
On Apr 1, 2009, at 8:07 AM, Benjamin Stiglitz wrote:
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension?
It is currently not implemented, but it's technically possible. A good work-around is to define accessors (properties) as John mentioned.
Maybe we need MacRuby::Runtime to bubble up the Obj-C runtime. Or FFI.
Might be a nice feature, but in this case I think we should simply expose the existing Objective-C ivars in variable.c, by adding another lookup path. If someone is willing to investigate that let me know. Should not be that hard.
Laurent _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
In this case, you could use the KVC[1] (key-value coding) accessor (#valueForKey:) to access the ivar. class Example def methodB self.valueForKey("instVarB") end end [1]: http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Con... Brian On Mon, Mar 30, 2009 at 9:27 AM, Edward Hynes <ehynes@dharmagaia.com> wrote:
Is there a way to access instance variables defined in an Objective-C class from a Ruby extension? I'm porting some of Apple's example code to MacRuby as a learning experience and would like to do so incrementally. Porting the code one class at a time works fine, but for some of the larger classes I'd like to port them a few methods at a time. Here's an example of what's happening
--- Example.h ---
@interface Example : NSObject { NSString *instVarA; NSString *instVarB; }
- (NSString *)methodA; @end
--- Example.m ---
#import "Example.h"
@implementation Example - (id)init { if (self = [super init]) { instVarA = @"instVarA"; instVarB = @"instVarB"; } return self; }
- (NSString *)methodA { return instVarA; }
@end
--- Example.rb ---
class Example def methodB @instVarB end end
Then at runtime, when I execute the following...
example = Example.alloc.init puts example.methodA.inspect puts example.methodB.inspect
.. I get
"instVarA" nil
How do I access InsVarB from Ruby?
Thanks, Ed
_______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel
participants (6)
-
Benjamin Stiglitz
-
Brian Chapados
-
Edward Hynes
-
John Shea
-
Laurent Sansonetti
-
Mathias Sulser