Hi there.
Er, I first had to find out that this is a mailing list and no
newsgroup. I signed at google groups, posted messages and wondered
why they actually are not there when I browsed the list at
nntp.perl.org. At www.perl.org I actually figured that this is a
list. Ohh dear.
So if the messages that I've send through google are arriving after
all, i'd like to appologize just now. :)
I am almost new to Perl. I like it and tried to use it in some of my
Cocoa Projects.
Just calling perl subroutines from C in't a problem with embedding a
Perl Interpreter. But passing arguments from and to the perl script
over pipe isn't what I want. If I could pass and get arguments or
variables in a OO manner that would be great. If nothing else works,
I probably have to deal with the pure C solution. But I first wanted
to test other possibilities.
I found there are two approaches. PerlObjCBridge and CamelBones.
Unfortunately I couldn't find any examples covering what I try to do.
I tested it with CamelBones first. Maybe someone can tell me whether
this would be possible with PerlObjCBridge, too.
I played a bit and that's what I figured so far. But unfortunately
I wasn't successfull in creating a CBPerlObject. I tried it from a
Foundation Project.
<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];
//[perl useWarnings]; // activate warnings
//[perl useLib:modulePath];
[perl useModule:@"SomePerl"];
[perl eval:@"$somePerl = new SomePerl"];
CBPerlObject *perlO = [perl namedObject:@"somePerl"];
[pool release];
return 0;
}
</objc_code>
The SomePerl.pm file looks like this:
<perl_code>
package SomePerl;
use strict;
use warnings;
sub new
{
my $class = shift;
my %attr = @_;
my $self = { %attr };
return bless ($self,$class);
}
1;
__END__
</perl_code>
The -namedObject: returns a nil pointer, so something goes wrong
there, but I couldn't figure out what.
As you can see I sent the -useLib: message and extended the library
search path to where the SomePerl.pm module is. So I guess the module
itself should be found.
Can someone please give me some hints?
Thx,
Manfred
> 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>
[quoted text clipped - 6 lines]
> // 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
Manfred Bergmann - 27 Oct 2005 03:27 GMT
Thanks sherm for replying.
Am 27.10.2005 um 11:50 schrieb Sherm Pendley:
> CBPerl is a singleton, so it's better to use the class method to
> access the shared instance:
>
> CBPerl *perl = [CBPerl sharedPerl];
That doesn't work here. Get a nil pointer returned.
> Should be:
>
[quoted text clipped - 3 lines]
> compiler doesn't know about the SomePerl class at compile time. The
> call to NSClassFromString() is needed for the same reason.
That either returns a nil pointer. Where does the ObjC runtime system
look for the SomePerl.pm file.
I placed it in some locations, so it should be found by whom ever. ;)
How does this work in general, maybe I can figure out where the
problem is.
> SomePerl.pm should look like this:
>
[quoted text clipped - 18 lines]
> return $self;
> }
Ok, done that.
Regards,
Manfred
Sherm Pendley - 27 Oct 2005 04:02 GMT
> Am 27.10.2005 um 11:50 schrieb Sherm Pendley:
>
[quoted text clipped - 4 lines]
>
> That doesn't work here. Get a nil pointer returned.
I forgot a recent addition, sorry. Should be:
#import <CamelBones/AppMain.h>
[CBPerl stubInit: CBGetPerlArchver()];
CBPerl *perl = [CBPerl sharedPerl];
>> id perlO = [[NSClassFromString(@"SomePerl") alloc] init];
>>
[quoted text clipped - 4 lines]
> That either returns a nil pointer. Where does the ObjC runtime
> system look for the SomePerl.pm file.
As far as the ObjC runtime goes, if a class hasn't yet been
registered, it calls a CamelBones "class handler" function. That
function tries to do an ordinary "use ClassName" to try to load and
register the class. That "use" looks in the standard @INC.
When CamelBones starts up, it adds the Resources/ sub-directories of
all linked frameworks and bundles (including the .app bundle) to
@INC, and platform- and version- specific subdirectories under that.
For instance, on Tiger it would add:
Resources/
Resources/5.8.6/
Resources/5.8.6/darwin-thread-multi-2level/
This is repeated whenever a new bundle is loaded by way of NSBundle
methods - any Objective-C classes in the bundle are automatically
wrapped to be visible from Perl, and the bundle's Resources/ sub-
directory is added to @INC.
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
Manfred Bergmann - 27 Oct 2005 04:27 GMT
Ok, that worked. Thanks.
Hmm, how come that I couldn't find any documentation about this? All
I found was a little example code on a japaneese internet site where
you couldn't read anything except the code snippet itself. :) This
was, as you said, an old example with CBPerlObject but it gave me a
hint how to begin at all with that.
Or maybe I am just incapable of searching in the internet. ;)
I figured CamelBones is pretty nice, not only for doing complete Perl-
Cocoa applications for which a lot of examples exist.
Ok, another question.
I guess the Xcode codesence is not working for any Perl classes and
methods, right?
And can I somehow get rid of the warning message from gcc that the
object xxx might not respond to method yyy if calling a method of a
Perl class?
Manfred
Am 27.10.2005 um 13:02 schrieb Sherm Pendley:
>> Am 27.10.2005 um 11:50 schrieb Sherm Pendley:
>>
[quoted text clipped - 43 lines]
> Cocoa programming in Perl: http://camelbones.sourceforge.net
> Hire me! My resume: http://www.dot-app.org
Joel Rees - 27 Oct 2005 04:34 GMT
> Ok, that worked. Thanks.
>
[quoted text clipped - 6 lines]
> I figured CamelBones is pretty nice, not only for doing complete
> Perl-Cocoa applications for which a lot of examples exist.
Too many of us who would like to use it don't have enough time to,
which is a shame.
> [...]
Sherm Pendley - 27 Oct 2005 05:16 GMT
> Hmm, how come that I couldn't find any documentation about this?
Because I haven't written any. ;-)
Why haven't I written any? Because I haven't really considered this
side of things - calling Perl from Objective-C - as being "final". It
has been primarily an internal API, and as you've seen from the old
code you looked at, things have changed substantially. It's pretty
well settled down at this point though, so it might well be time to
write those docs.
> I guess the Xcode codesence is not working for any Perl classes and
> methods, right?
No, it's not. It doesn't know about the Perl debugger either.
> And can I somehow get rid of the warning message from gcc that the
> object xxx might not respond to method yyy if calling a method of a
> Perl class?
You could do what Apple does with delegate methods - declare them in
a category of NSObject:
@interface NSObject (MyPerlClassMethods)
- (id) doFoo:(id)foo;
@end
You don't have to provide an @implementation for them - that's in
Perl. If you declare them in the main @interface, but don't provide
an @implementation, the linker complains. But, with the declarations
in a category, the linker is quiet. That's by design, for situations
like this, where you need to declare an interface for methods that
are not loaded until run time.
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org