[MacRuby-devel] Obj-C object allocation and consistency in Ruby

Laurent Sansonetti lsansonetti at apple.com
Thu May 29 14:19:23 PDT 2008


Hi Brian,

On May 29, 2008, at 6:07 AM, Brian Mitchell wrote:

> I've been playing around with objects a bit and have noticed the
> Objective-C interfaces for object allocation are available. I'm not an
> regular Objective-C user so this is all from my limited knowledge.
>
> In MacRuby, one can currently get away with something like
> NSCFString.alloc, and it seems to not cause any immediate crashes if
> init is not called right after. This is a dangerous assumption of
> course. If I simply try calling on a different class where init is
> more important it will quickly cause a crash:
> NSMutableString.alloc.size.
>
> In Objective-C the pattern is (AFAICT) usually something like
> [[MyClass alloc] initOfSomeSort]. It makes sense and the
> responsibility is on the developer to keep things consistent. In Ruby
> code however, I would expect these sorts of issues to either be
> handled or be impossible to occur in pure Ruby. Now there might be a
> way to handle errors better (i.e. catching the
> NSInvalidArgumentException in the above example) and prevent bad
> crashes that currently occur but is this sort of thing just going to
> become a side effect of living on top of an Objective-C style class
> hierarchy and protocol? I'd really like to avoid getting segmentation
> faults and other lower level problems in Ruby code. (Though I don't
> mind paying the price if this gets to what 1.0 has promised. ;-) )

First of all, one thing that might be important to notice is that  
MacRuby runs in an Objective-C garbage collected environment. Which  
means that you can use the Objective-C interfaces to create objects,  
but there is no need to retain/release/autorelease objects.

Regarding the [alloc [init ... pattern, it's unfortunately  
unavoidable. init must follow alloc, and there are many cases in Cocoa  
where not doing this will result in a very bad behavior (we  
experimented this in RubyCocoa). Trying to catch a potential exception  
might work in some cases, but fail in others (one example, NSView).

Nevertheless, it is still possible to create objects with #new.

 >> v = NSView.new # instead of NSView.alloc.initWithFrame(...)
=> #<NSView:0x2f9d060>
 >> v.frame
=> #<NSRect origin=#<NSPoint x=0.0 y=0.0> size=#<NSSize width=0.0  
height=0.0>>
 >> v.frame = [1, 2, 3, 4]
=> [1, 2, 3, 4]
 >> v.frame
=> #<NSRect origin=#<NSPoint x=1.0 y=2.0> size=#<NSSize width=3.0  
height=4.0>>
 >> v.subviews
=> []
 >> v.addSubview NSButton.new
=> nil
 >> v.subviews
=> [#<NSButton:0x28aea50>]

Laurent


More information about the MacRuby-devel mailing list