Re: PerlObjCBridge and selectors

[email protected] (Doug Wiebe)
Newsgroups perl.macosx
Message-ID <[email protected]>
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: [email protected]
> 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 <[email protected]>') : ()),
     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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.