Inlineで遊ぼう Tomohiro IKEBE <[email protected]> EDGE Co., ltd. Shibuya.pm Techinical Talks 目次 Inline とは なぜInlineなのか Inline::C Inline::Java Inline::Ruby ILSM を作る まとめ Inline とは DESCRIPTION The Inline module allows you to put source code from other programming languages directly "inline" in a Perl script or module. The code is automatically compiled as needed, and then loaded for immediate access from Perl. Perl プログラムの中に “直接” 他の言語を記述するためのモジュール コンパイルが必要な場合は自動的にコンパイルされ、他の言語で書かれたサ ブルーチンやクラスをPerlから使用する事が出来る。 C,C++ の他に ILSM (Inline Language Support Module) と呼ばれる機構により、 様々な言語を使用する事が出来る。 ILSM Inline::ASM Inline::Awk Inline::BC Inline::Basic Inline::Befunge Inline::C Inline::CPP Inline::Guile Inline::Java Inline::Octave Inline::Python Inline::Ruby Inline::Slang Inline::SMITH Inline::TT Inline::Tcl Inline::WebChat Acme::Inline::PERL Inline 以前 XS Perl 標準の拡張方法 マクロを使って記述 モジュールを作成する事が前提 SWIG (http://www.swig.org/) Perl 以外の言語も対応 定義ファイルからソースコードを生成 なぜInlineなのか より高速な言語で一部を記述する。 既存の資産を利用する。 XSやSWIGはめんどくさい。 たまには他の言語もいいかな。。 Inline::C • 初回起動時はコンパイル処理が入るので遅い % time ./ghttp.pl 3.440u 1.140s 0:06.23 73.5% % time ./ghttp.pl 0.190u 0.060s 0:00.33 75.7% 0+0k 62+12io 0pf+0w 0+0k 0+1io 0pf+0w • カレントディレクトリに _Inline ディレクトリが生成され、その内部で コンパイル処理が行われる。 • Perl <=> C で取り扱える型。 • int • long • double • char* • void • SV* Inline::C • ヒアドキュメントで記述 use Inline C =><<‘C_SOURCE’; void say_hello (){ printf(“Hello World!\n”); } C_SOURCE say_hello(); • __DATA__ を使用 use Inline C => ‘DATA’; say_hello(); __DATA__ __C__ void say_hello (){ printf(“Hello World!\n”); } 外部ライブラリの使用 外部ライブラリを使用する。 use strict; use Inline C => Config => LIBS => '-L/sw/lib -lghttp', INC => '-I/sw/include'; print get('http://www.google.co.jp/'); __END__ __C__ #include <ghttp.h> SV *get(SV* uri) { SV* buffer; malloc(sizeof(char) * 1024 * 10); ghttp_request* request; buffer = NEWSV(0,0); request = ghttp_request_new(); ghttp_set_uri(request, SvPV(uri, PL_na)); ghttp_set_header(request, http_hdr_Connection, "close"); ghttp_prepare(request); ghttp_process(request); sv_catpv(buffer, ghttp_get_body(request)); ghttp_request_destroy(request); return buffer; } Inline::Java Java のクラスをPerlのクラスに 外部 Java クラスの使用 サーバとして動作する RPC JNI によるnative インターフェース Velocity を実行する。 Jakarta Project の Velocity を Perl による Web アプリケーションの テンプレートエンジンとして使用する。 便利かどうかは微妙なところ。。 use strict; use Inline ( Java => ‘DATA’, # DATA セクションに記述する CLASSPATH => ‘/path/to/velocity-1.3.jar’, # CLASSPATH を追加 DIRECTORY => ‘/tmp’, # httpd に書きこめるディレクトリ SHARED_JVM => 1, # JVM を共有する STUDY => [‘java.util.HashMap’], # HashMap を使用する ); use CGI; Inline::Java::release_JVM(); Velocity を実行する。 my $q = CGI->new; print $q->header; my $v = VelocityWrapper->new; my $map = java::util::HashMap->new(); # STUDY! $map->put($_, $q->param($_)) for $q->param; # パラメータ $v->set("request", $map); print $v->process("test.vm"); __DATA__ __Java__ #…. Velocity を実行する。 import java.io.StringWriter; import org.apache.velocity.app.Velocity; import org.apache.velocity.VelocityContext; import java.util.Properties; class VelocityWrapper { VelocityContext context = null; public VelocityWrapper(){ try { Velocity.init(new Properties()); } catch(Exception ex){ ex.printStackTrace(); } context = new VelocityContext(); } public void set(String key, Object obj){ context.put(key, obj); } public String process(String filename) throws Exception{ StringWriter w = new StringWriter(); Velocity.mergeTemplate(filename, context, w ); return w.toString(); } } Inline::Ruby Ruby のクラスをPerlから使用する。 組み込み型の相互変換。 rb_eval 関数 HTML::ERuby http://search.cpan.org/dist/HTML-ERuby/ Eruby を Perl で実装。 Eruby の文法を Perl でパースし、Rubyのソースコードを生成 rb_eval しているだけ Perl の Web アプリケーションでテンプレート的に使用。 my %vars = (‘@var’ => ‘foo’, # Ruby instance variable ‘ARRAY_REF’ => [qw(a b c)], # Ruby constant ‘hash_ref’ => {foo => ‘bar’, ‘bar’ => ‘baz’}); my $compiler = HTML::ERuby->new; print $compiler->compile(filename => ‘./foo.rhtml’, vars => ¥%vars); HTML::ERuby Ruby -> Perl のデータ受け渡しはあるが逆はサポートされてない。 Perl の HASH_REF, ARRAY_REF は見た目的に Ruby の配列、ハッシュ と似てる。。 そこで、Data::Dumper で Dump して Ruby で eval する事により配列、ハッ シュを引渡す。 In Perl. my %hash = (a => ‘foo’, b => ‘bar’); my $str = Dumper \%hash; $str =~ s/\$VAR1=//; In Ruby hash = eval $str まとめ まっとうに使うなら C, C++ Java は進化してきている。 スクリプト系は型のサポートが微妙 誰か Inline::PHP 作って。
© Copyright 2025 ExpyDoc