develooper Front page | perl.macosx | Postings from April 2008

Re: PerlObjCBridge and selectors

Thread Previous
From:
Doug Wiebe
Date:
April 18, 2008 12:55
Subject:
Re: PerlObjCBridge and selectors
Comments below. Hope this is not too late to be of help.

On Mar 12, 2008, at 4:24 AM, Pedro Melo wrote:
> Hi,
>
> I'm trying to tap into the NSDistributedNotificationCenter with Perl.
>
> The simplest script that almost works is this:
>
> #### START
> package Listener;
> use strict;
> use Foundation;
>
> sub start {
>  my ($class) = @_;
>  my $self = bless {}, $class;
>
>  my $center = NSDistributedNotificationCenter->defaultCenter;
>  $center->addObserver_selector_name_object_($self, 'updated',  
> "org.simplicidade.guy.whatsup", undef);
>  NSRunLoop->currentRunLoop->run;
> }
>
> sub updated {}
>
> package main;
> use strict;
>
> Listener->start;
>
> #### END
>
> I get the events but I cannot figure out how to pass a selector (the  
> 'updated' argument in the addObserver... call above) from Perl to  
> ObjC. I've also tried the following:
>
> * using base as PerlObjCBridge or NSObject;
> * using PerlObjCBridge::preloadSelectors('Listener');
> * using a anonymous coderef;
> * using a coderef to &updated.
>
> The following messages are generated when the notification is  
> received.
>
> 2008-03-12 10:14:11.710 perl[22003] *** -[PerlProxy updated]:  
> selector not recognized [self = 0x3323c0]
> 2008-03-12 10:14:11.710 perl[22003] Exception raised during posting  
> of notification.  Ignored.  exception: *** -[PerlProxy updated]:  
> selector not recognized [self = 0x3323c0]
>
> So the "updated" selector is recognized somehow, the then he uses a  
> PerlProxy base class? I could not find any documentation on PerlProxy.
>
> Any ideas on how to give a selector to objC?
>
> Thanks in advance,
> -- 
> Pedro Melo
> Blog: http://www.simplicidade.org/notes/
> XMPP ID: melo@simplicidade.org
> Use XMPP!



Try these steps:


# create a new Perl XSUB module
 > cd /tmp
 > h2xs -A -P -n Listener
 > cd Listener




# add an Objective-C stub for the "updated" method to Listener.xs
 > vi Listener.xs
 > cat Listener.xs
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#ifdef Move
#undef Move
#endif Move

#import <Foundation/Foundation.h>

@interface Listener: NSObject
@end

@implementation Listener

- (void)updated {}

@end

MODULE = Listener               PACKAGE = Listener




# add the Listener package code to Listener.pm
 > vi lib/Listener.pm
 > cat lib/Listener.pm
package Listener;

use 5.008008;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration       use Listener ':all';
# If you do not need this, moving things directly into @EXPORT or  
@EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(

) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(

);

our $VERSION = '0.01';

require XSLoader;
XSLoader::load('Listener', $VERSION);

# Preloaded methods go here.

use Foundation;

PerlObjCBridge::preloadSelectors('Listener');

sub new {
    return bless {};
}

sub updated {
     printf "Here in updated\n";
}

1;



# add "-ObjC" to INC field in Makefile.PL
 > vi Makefile.PL
 > cat Makefile.PL

use 5.008008;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
     NAME              => 'Listener',
     VERSION_FROM      => 'lib/Listener.pm', # finds $VERSION
     PREREQ_PM         => {}, # e.g., Module::Name => 1.1
     ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
       (ABSTRACT_FROM  => 'lib/Listener.pm', # retrieve abstract from  
module
        AUTHOR         => 'Doug <doug@apple.com>') : ()),
     LIBS              => [''], # e.g., '-lm'
     DEFINE            => '', # e.g., '-DHAVE_SOMETHING'
     INC               => '-I. -ObjC', # e.g., '-I. -I/usr/include/ 
other'
         # Un-comment this if you add C files to link with later:
     # OBJECT            => '$(O_FILES)', # link all the C files too
);



# build and install the module
 > perl Makefile.PL INSTALLDIRS=site
 > make
 > make test
 > sudo make install



# write the listener tool
 > touch listener
 > chmod +x listener
 > vi listener
 > cat testFoo
#!/usr/bin/perl

use strict;
use warnings;

use Listener;

my $listener = new Listener;
my $center = NSDistributedNotificationCenter->defaultCenter;
$center->addObserver_selector_name_object_( $listener, 'updated',  
'foo.bar.baz', undef );
NSRunLoop->currentRunLoop->run;



# write the sender tool
 > touch sender
 > chmod +x sender
 > vi sender
 > cat sender
#!/usr/bin/perl

use strict;
use warnings;

use Foundation;

my $center = NSDistributedNotificationCenter->defaultCenter;
$center- 
 > 
postNotificationName_object_userInfo_deliverImmediately_ 
( 'foo.bar.baz', undef, undef, 1 );



# run the listener tool in one shell
 > ./listener



# run the sender tool in a different shell
 > ./sender



You should see the listener tool emit:
Here in updated

- Doug



Thread Previous


Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About