Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Hacking Mac OS X Cocoa API from Perl
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
typester
November 18, 2011
Programming
430
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Hacking Mac OS X Cocoa API from Perl
YAPC::Asia 2011 Tokyo
typester
November 18, 2011
More Decks by typester
See All by typester
サーバーサイドエンジニアのためのiOSアプリ開発入門
typester
0
4.8k
Emacs実践入門 Perl編
typester
0
2.7k
XSにまつわる話
typester
4
2.2k
Perlハッカーは息をするようにCPANモジュールを書く
typester
5
7.5k
UV - libuv binding for Perl
typester
1
6.2k
Other Decks in Programming
See All in Programming
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
9
3.6k
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
250
AI がコードを書く時代における新卒エンジニアの仕事風景 (2026) / New Graduate Engineers in the Era of AI Coding (2026)
sushichan044
0
240
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
360
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
200
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
110
霧の中の代数的エフェクト
funnyycat
1
440
Build-to-own AI: Agentic Development for Humans
inesmontani
PRO
0
100
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
180
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
320
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
210
Featured
See All Featured
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
530
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
390
Building Adaptive Systems
keathley
44
3.1k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
AI: The stuff that nobody shows you
jnunemaker
PRO
9
850
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.5k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
1k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Being A Developer After 40
akosma
91
590k
Transcript
)BDLJOH.BD049$PDPB"1* GSPN1FSM %BJTVLF.VSBTF UZQFTUFS :"1$"TJB5PLZP
"CPVUNF w %BJTVLF.VSBTF w ,":"$*OD QSFTFOU w 5IJTZFBS`TXPSL
"CPVUNF w %BJTVLF.VSBTF w ,":"$*OD QSFTFOU w 5IJTZFBS`TXPSL w 3FFOHP
'BDFCPPLJOUFHSBUFE7P*1BQQMJDBUJPOGPSJ04
"CPVUNF w %BJTVLF.VSBTF w ,":"$*OD QSFTFOU w 5IJTZFBS`TXPSL w 3FFOHP
'BDFCPPLJOUFHSBUFE7P*1BQQMJDBUJPOGPSJ04 w 72$IFDLFS 7PJDF2VPUJFOUBOBMZ[FSGPS1$BOEJ04
"CPVUNF w %BJTVLF.VSBTF w ,":"$*OD QSFTFOU w 5IJTZFBS`TXPSL w 3FFOHP
'BDFCPPLJOUFHSBUFE7P*1BQQMJDBUJPOGPSJ04 w 72$IFDLFS 7PJDF2VPUJFOUBOBMZ[FSGPS1$BOEJ04 w 0OFNPSFUIJOH 8JMMCFSFMFBTFECFGPSFUIJTYNBT
"CPVUNF w BLBUZQFTUFS
"CPVUNF w BLBUZQFTUFS w IUUQTFBSDIDQBOPSHd5:1&45&3 w IUUQHJUIVCDPNUZQFTUFS w IUUQGBDFCPPLDPNUZQFTUFS w
IUUQUXJUUFSDPNUZQFTUFS
—.B[EB3PBETUFS LOPXOBT.9JOPUIFSDPVOUSJFT
"HFOEB w "MJUUMFLOPXMFEHFBCPVU0CKFDUJWF$ w )PXUPVTF0CKFDUJWF$GSPN1FSM w "MJUUMFLOPXMFEHFBCPVU94 w 4PNFUJQTBCPVU94BOE0CKFDUJWF$ w
*OUSPEVDJOH$PDPBNPEVMFT*`WFDSFBUFE
0CKFDUJWF$
0CKFDUJWF$ w $SFBUFEGPS/FYU4UFQ w *U`TDVSSFOUMZVTFEBTQSJNBSZ QSPHSBNNJOHMBOHVBHFGPS.BD049 w *NQMFNFOUFECBTFE$ "MM$TZOUBYBOEGFBUVSFTDBOCFVTFEJO 0CKFDUJWF$pMF
0CKFDUJWF$ • #import <Foundation/Foundation.h> int main(int argc, char** argv) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; // Objective-C code here NSLog(@”Hello World!”); [pool drain]; return 0; }
0CKFDUJWF$ w HDDGSBNFXPSL'PVOEBUJPOGPPN
0CKFDUJWF$ w HDDGSBNFXPSL'PVOEBUJPOGPPN w MJLFHDDM'PVOEBUJPOGPPD
0CKFDUJWF$ w HDDGSBNFXPSL'PVOEBUJPOGPPN w MJLFHDDM'PVOEBUJPOGPPD w BPVU
94 w 'PPYTpMFJTOPUVTFEJSFDUMZGPS$ DPNQJMFS w 'PPYTXJMMDPOWFSU'PPDCZYTVCQQ w :PVDBOXSJUF'PPDEJSFDUMZJGZPVXBOU
'PPD • #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h"
XS(func) { dXSARGS; // code here XSRETURN(0); } XS(boot_Foo) { newXS("Foo::xs_function", func, __FILE__); }
QBDLBHF'PP •package Foo; use strict; use XSLoader; XSLoader::load __PACKAGE__, $VERSION;
1;
3VOJU •use Foo; Foo::xs_function();
.BLFpMF1-GPS'PPD • use inc::Module::Install; # some basic descriptions here use_ppport
'3.19'; WriteAll; w .PEVMF*OTUBMM946UJM w 4FFBMTP%BUB.FTTBHF1BDL %BUB".'94 UIBUJTVTJOH UIJTQTFVEP94UFDIOJRVF
.BLFpMF1-GPS'PPN
.BLFpMF1-GPS'PPN w VTFJOD.PEVMF*OTUBMM TPNFCBTJDEFTDSJQUJPOTIFSF VTF@QQQPSU DD@BQQFOE@UP@MJCTMPCKD NBLFNBLFS@BSHT\EZOBNJD@MJC^\ 05)&3-%'-"(4GSBNFXPSL'PVOEBUJPO ^ \
IUUQXXXNBJMBSDIJWFDPNNBLFNBLFS!QFSMPSHNTHIUNM "EETPNFSFRVJSFENBDIJOFSZUPTVQQPSUNpMFT QBDLBHF.: TVCD@P\ NZJOIFSJUFETIJGU461&3D@P !@ JOIFSJUFE&0.&44 N 0#+@&95 $$$.% $$$%-'-"(4 * 1&3-@*/$ 1"45)36@%&'*/& %&'*/& N &0.&44 JOIFSJUFE ^ TVCYT@D\ NZJOIFSJUFETIJGU461&3YT@D !@ JOIFSJUFE&0.&44 YTN 946#1136/ 9413050"3( 946#11"3(4 946#11@&953"@"3(4 YT YTN .7 YTN N &0.&44 JOIFSJUFE ^ TVCJOJU@EJSTDBO\ NZTFMGTIJGU TFMG461&3JOJU@EJSTDBO GPSFBDINZOBNF TFMGMTEJS TFMGDVSEJS \
.BLFpMF1-GPS'PPN w 4PSSZ
.BLFpMF1-GPS'PPN w 4PSSZ w 4FF$PDPB bT.BLFpMF1- w IUUQTNFUBDQBOPSHTPVSDF5:1&45&3 $PDPB&WFOU-PPQ.BLFpMF1-
5IBU`TJU w 0CKFDUJWF$JOWPMWFBMM$GVODUJPOTBOE GFBUVSFT w +VTUSFOBNF'PPDUP'PPN JUDPNQMFUFMZ XPSLTCZUIJT.BLFpMF1- w "OEPGDBVTF
ZPVDBOVTF0CKFDUJWF$ TQFDJpDTZOUBYJOUIJTpMF
)FMMPN • #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h"
// undefine Move macro, this is conflict to Mac OS X QuickDraw API. #undef Move #import <Foundation/Foundation.h> XS(hello) { dXSARGS; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Hello!"); [pool drain]; XSRETURN(0); } XS(boot_Hello) { newXS("Hello::hello", hello, __FILE__); }
$PQJFTBOEQBTUFTGPS94 •#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h"
$PQJFTBOEQBTUFTGPS94 •#undef Move
$PQJFTBOEQBTUFTGPS94 •XS(function) { dXSARGS; // code here XSRETURN(0); }
$PQJFTBOEQBTUFTGPS94 •XS(function) { dXSARGS; // code here ST(0) = some_sv;
XSRETURN(1); }
$PQJFTBOEQBTUFTGPS94 •XS(function) { dXSARGS; // code here ST(0) = some_sv;
ST(1) = some_sv2; XSRETURN(2); }
$PQJFTBOEQBTUFTGPS94 • XS(function) { dXSARGS; SV* sv_args1 = ST(0); SV*
sv_args2 = ST(1); // code here ST(0) = some_sv; ST(1) = some_sv2; XSRETURN(2); }
$PQJFTBOEQBTUFTGPS94 • XS(function) { dXSARGS; if (items < 2) {
Perl_croak(aTHX_ "Usage: function($args1, $args2)"); } SV* sv_args1 = ST(0); SV* sv_args2 = ST(1); // code here ST(0) = some_sv; ST(1) = some_sv2; XSRETURN(2); }
GPS0CKFDUJWF$BOE1FSM w 1FSMTUSJOHUP/44USJOH STRLEN len; char* c = SvPV(sv, len);
NSString* str = [NSString stringWithUTF8String:c]; w /44USJOHUP1FSMTUSJOH SV* sv = sv_2mortal(newSV(0)); sv_setpv(sv, [str UTF8String]);
GPS0CKFDUJWF$BOE1FSM w 1FSMOVNCFSUP/4/VNCFS NSNumber* n; if (SvNOKp(sv)) { n =
[NSNumber numberWithDouble:(double)SvNVX(sv))]; } else if (SvIOK_UV(sv)) { n = [NSNumber numberWithDouble:(double)SvUV(sv))]; } else if (SvIOKp(sv)) { n = [NSNumber numberWithDouble:(double)SvIV(sv))]; } w /4/VNCFSUP1FSMOVNCFS SV* sv = sv_2mortal(newSVnv([n doubleValue]));
GPS0CKFDUJWF$BOE1FSM w 4OJQ EFTDSJCFEJONZCMPHMBUFS w 1FSMBSSBZUP/4"SSBZ w /4"SSBZUP1FSMBSSBZ w 1FSMIBTIUP/4%JDUJPOBSZ
w /4%JDUJPOBSZUP1FSMIBTI
%PO`UGPSHFU w FOBCMF/4"VUPSFMFBTF1PPMTDPQFBSPVOE ZPVS/4 PCKFDUT w PUIFSXJTFUIFDPEFXJMMDSBTI
:PVSGSJFOET w QFSMEPDQFSMHVUT w QFSMEPDQFSMBQJ w YDPEFEPDVNFOUBUJPO
$PDPBNPEVMFT
$PDPBNPEVMFT w $PDPB&WFOU-PPQ w $PDPB(SPXM w "OZ&WFOU*NQM$PDPB
$PDPB&WFOU-PPQ w QSPWJEFTQFSMJOUFSGBDFGPS$PDPBTFWFOU MPPQ /43VO-PPQ w BMTPQSPWJEFTUJNFST *0XBUDIFSTBDUT XJUIUIBUFWFOUMPPQ w
:PVDBOIBOEMFFWFOUDBMMCBDLTDPSSFDUMZ CZVTJOHUIJTNPEVMF
$PDPB(SPXM w 1FSMJOUFSGBDFGPS(SPXMGSBNFXPSL w 4VQQPSUDMJDLFWFOUXJUI $PDPB&WFOU-PPQ
$PDPB(SPXM •use Cocoa::Growl ':all'; my $installed = growl_installed(); my $running
= growl_running();
$PDPB(SPXM • use Cocoa::Growl ':all'; # register application growl_register( app
=> 'My growl script', icon => '/path/to/icon.png', # or 'http://urlto/icon' notifications => [qw(Notification1 Notification2)], );
$PDPB(SPXM •use Cocoa::Growl ':all'; # show growl notification growl_notify( name
=> 'Notification1', title => 'Hello!', description => 'Growl world!', );
$PDPB(SPXM • use Cocoa::EventLoop; use Cocoa::Growl ':all'; growl_register( name =>
'test script', notifications => ['test notification'], ); my $wait = 1; growl_notify( name => 'test notification', title => 'Hello', description => 'Growl World!', on_click => sub { warn 'click'; $wait = 0; }, on_timeout => sub { warn 'timeout'; $want = 0; }, ); Cocoa::EventLoop->run_while(0.1) while unless $wait;
"OZ&WFOU*NQM$PDPB w "OZ&WFOUBEBQUPSGPS$PDPB&WFOU-PPQ w ZPVDBOVTF$PDPBCBTFE"1*JOZPVS "OZ&WFOUBQQMJDBUJPO PS"OZ&WFOUXJUIJO $PDPBBQQMJDBUJPOT
"OZ&WFOU*NQM$PDPB w +VTUEPUIJT use AnyEvent; use Cocoa::EventLoop; # then all
anyevent based api use Cocoa::EventLoop!
"OZ&WFOU*NQM$PDPB • use AnyEvent; use Cocoa::EventLoop; use Cocoa::Growl; my $cv
= AE::cv; growl_notify( name => 'test notification', title => 'Hello', description => 'Growl World!', on_click => sub { warn ‘click’; $cv->send; }, on_timeout => sub { warn ‘timeout’; $cv->send; }, ); $cv->recv;
&OKPZ