[RubyCocoa] Cocoa Bindings? (cont.)

Hello,

(to Kevin Bullock in this group: when searching for a solution, I saw
your answer to my earlier question in c.l.r. about this, not here in
c.l.r., but on some ruby-talk site, where you asked for the source
code of the dummy app: I included it here. I also followed the
instructions suggested on the ruby-cocoa mailing list at sourceforge,
alas, no show yet ...)

My first question is: has anyone had any succes in building and
running a RubyCocoa / Cocoa Bindings (aka Cocoa Controller Layer)
project? I tried to do a dummy-app along the execellent tutorial at
(using ruby1.8 instead of ObjC):

http://www.macdevcenter.com/pub/a/mac/2004/04/06/cocoa.html?page=1

Building the interface according this tutorial and test-driving it in
Interface Builder works fine.

In a first attempt, my Book.rb looked like this:

class Book < OSX::NSObject
    attr_accessor :title
    attr_accessor :author
end

Running the app gave me this error:

/Users/hvs/tmp/bibliotecha/build/bibliotecha.app/Contents/Resources/
rb_main.rb:19:in
`NSApplicationMain': NSApplicationMain - NSUnknownKeyException -
[<Book 0x4f2540> valueForUndefinedKey:]: this class is not key value
coding-compliant for the key title. (OSX::OCException)
   from
/Users/hvs/tmp/bibliotecha/build/bibliotecha.app/Contents/Resources/
rb_main.rb:19

After reading some more docs on Apple's ADC site, about key value
coding (KVC) -compliancy, I change my code to:

class Book < OSX::NSObject
    attr :title
    attr :author
    
    def title
        return @title
    end
    
    def author
        return @author
    end
    
    def setTitle(title)
        @title = title
    end
    
    def setAuthor(author)
        @author = author
    end
end

It's ugly, but a KVC-compliant object needs set<Key> methods. But this
gave me the same error.

How to make Book KVC-compliant???

thx,
Harry

Harry wrote:

It's ugly, but a KVC-compliant object needs set<Key> methods. But this
gave me the same error.

How to make Book KVC-compliant???

thx,
Harry

Harry,

I'm kind of flying blind here, but from what I remember about Apple's KeyValueCoding protocol, it's only necessary to implement a couple of methods. In more-or-less Obj-C form (I'm rusty), the first two are

- (id)valueForKey: aKey
- (void *)takeValue: someValue forKey: someKey

In other words, KVC is designed to circumvent setFoo/getFoo methods, not to require them.

There is, IIRC, at least one other method needed for strict compliance, somthing to do with handling unbound (unrecognized) keys, but I can't remember the precise name or use. I think on the Foundation Kit side, Apple may still include some default KVC behavior to relieve you from the need of implementing this.

Also, you might make sure that you're passing in first-class objects (as Obj-C defines them, meaning non-scalars). Earlier versions of Foundation Kit permitted a mixed approach, depending on the type of the ivar, but I do believe that later, Java-based versions standardized on wrapped primitives.

I hope at least some of that is useful, and wish I had Cocoa + Ruby to fiddle with these days :slight_smile:

- dan

···

--
...
... dhtapp is a cox dot net account
...

Dan Tapp <dhtapp@see_sig_line.com> wrote in message news:<SkEGc.54123$Yu.29363@fed1read04>...

I'm kind of flying blind here, but from what I remember about Apple's
KeyValueCoding protocol, it's only necessary to implement a couple of
methods. In more-or-less Obj-C form (I'm rusty), the first two are

- (id)valueForKey: aKey
- (void *)takeValue: someValue forKey: someKey

Yes, they are part of the NSKeyValueCoding protocol and should be
implemented by the base-class NSObject, as described on Apple's ADC
site:

'Key-value coding in Objective-C is largely managed by the
NSKeyValueCoding informal protocol, which is implemented by the
NSObject class.'

In other words, KVC is designed to circumvent setFoo/getFoo methods, not
  to require them.

And (also on that site (I'm not sure the urls for that site are
persistent, so I'll just quote the text)):

'In order for a class to be considered KVC compliant for a specific
property, it must implement the methods required for valueForKey: and
setValue:forKey: to work for that property.

For properties that are an attribute or a to-one relationship, this
requires that:

    * Your class implements a method named -<key>, -is<Key>, or have
an instance variable <key> or _<key>.
    * If the property is mutable, then it should also implement
-set<Key>:.
    * Your implementation of the -set<Key>: method should not perform
validation.
    * Your class should implement -validate<Key>:error: if validation
is appropriate for the key.'

There is, IIRC, at least one other method needed for strict compliance,
somthing to do with handling unbound (unrecognized) keys, but I can't
remember the precise name or use. I think on the Foundation Kit side,
Apple may still include some default KVC behavior to relieve you from
the need of implementing this.

Also, you might make sure that you're passing in first-class objects (as
  Obj-C defines them, meaning non-scalars). Earlier versions of
Foundation Kit permitted a mixed approach, depending on the type of the
ivar, but I do believe that later, Java-based versions standardized on
wrapped primitives.

Can you elaborate on that? I'm rusty in language intrinsics ...

I hope at least some of that is useful, and wish I had Cocoa + Ruby to
fiddle with these days :slight_smile:

Thx for answering Dan! Yep, same here, alas it doesn't get much
further then fiddling right now ... pretty much stuck with the
combined RubyCocoa + Cocoa Bindings thing, which I believe is the best
thing since sliced bread ... :wink:

Harry