On Oct 26, 2005, at 8:34 PM, Manfred Bergmann wrote:

I played a bit and that's what I figured so far. But unfortunately
I wasn't successfull in creating a CBPerlObject.

CBPerlObject is a relic from 0.2.x, from when an Objective-C proxy was needed as a stand-in. With 1.0.x, Perl classes, when properly declared as subclasses of NSObject, are first-class citizens that don't need the proxy.

<objc_code>
#import <Foundation/Foundation.h>
#import <CamelBones/CamelBones.h>

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // create perl interpreter
    CBPerl *perl = [[CBPerl alloc] init];

CBPerl is a singleton, so it's better to use the class method to access the shared instance:

        CBPerl *perl = [CBPerl sharedPerl];

    //[perl useWarnings];   // activate warnings
    //[perl useLib:modulePath];
    [perl useModule:@"SomePerl"];

The following two lines should be replaced:

    [perl eval:@"$somePerl = new SomePerl"];
    CBPerlObject *perlO = [perl namedObject:@"somePerl"];

Should be:

        id perlO = [[NSClassFromString(@"SomePerl") alloc] init];

Note that perlO is typed as "id". That's necessary because the compiler doesn't know about the SomePerl class at compile time. The call to NSClassFromString() is needed for the same reason.

    [pool release];

    return 0;

}
</objc_code>

...snip...

SomePerl.pm should look like this:

    package SomePerl;

    use CamelBones qw(:All);

    use strict;
    use warnings;

    class SomePerl {
        'super' => 'NSObject',
        'properties' => [ 'foo', 'bar', 'baz' ],
    };

    sub init : Selector(init) ReturnType(@) {
        my ($self) = @_;
        $self = $self->SUPER::init();

        # Do other initialization

        return $self;
    }

Note that object creation follows Cocoa, rather than Perl conventions. You use the inherited alloc() class method to create an instance, and initialize the instance by overriding the init() instance method, making sure to call the superclass' init() first.

The call to class() and the method attributes are key here. The class () function registers the Perl class and its methods with the Objective-C runtime. The attributes are used to declare the selector, argument, and return types with which the method can be called from Objective-C. So, for instance, let's say you have a method that, in Objective-C, would be declared like this:

    - (id) doFoo:(id)foo withBar:(id)bar options:(int)opts;

In Perl, you'd write it like this:

sub doFoo_withBar_options : Selector(doFoo:withBar:options:) ReturnType(@) ArgTypes(@@i) {
        my ($self, $foo, $bar, $opts) = @_;
    }

The 'properties' hash key defines a list of, ummm, properties. ;-) KVC-compliant accessor methods are defined for each, so they can be used as outlets, in Cocoa Bindings, etc. For instance, declaring the property 'foo' would cause the following accessor methods to be defined, that can be called from both Objective-C and Perl:

    sub foo : Selector(foo) ReturnType(@) {
        my ($self) = @_;
        return $self->{'foo'};
    }

    sub setFoo : Selector(setFoo:) ArgTypes(@) {
        my ($self, $value) = @_;
        $self->{'foo'} = $value;
    }

sherm--

Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org

Reply via email to