BridgeBetweenStrongAndLoose
強い型付言語と弱い型付言語の相互運用
多言語のブリッジを開発する場合、いくつかの考慮点がある。
ここでは以下の2点のうち、特に後者について考察する。
- 型システムの差
- メソッドシグネチャに型情報が含まれるメソッドの特定手法
これは、RjbおよびASR(およびその元となったWin32OLE)における相互運用上のデザインについてのメモである。
具体例
Rjbを例とする。今、以下のスクリプトを実行していると仮定する。
JString = Rjb::import('java.lang.String') s = JString.new("ABC") t = JString.new("\x01\0\x02\0\x03\0")
人間の意図として、これは以下のJavaのプログラムに相当することが考えられる。
String s = new String("ABC"); String t = new String(new byte[] { 1, 0, 2, 0, 3, 0 });
すなわち、最初のコンストラクタの呼び出しは、String(String)、次のコンストラクタの呼び出しは、String(byte[]) である。
しかし、Rubyにはbyte[]に相当する型はないため、このような判定を機械的に正しく行う手段はない。
ユースケースによる判定
この例で示したStringクラスのコンストラクタについては、String(String)の呼び出しに意味がないため、おそらくString(byte[])の呼び出しと判断することは間違いではないだろう。
しかし、これは他のメソッドについて敷衍できるわけではない。
したがって、ユースケースからの考察は現実的な判定方法とは言えない。
判定方法の種類
- 自動判定
- 最初にマッチした(コアース可能な)メソッド
- 呼び出しコスト低、信頼性無
- 最後にマッチしたメソッド(全メソッドとマッチ)
- 呼び出しコスト高、信頼性無
- ユースケースの内蔵
- 非現実的
- 優先するメソッドの構成表
- APIとして実装すれば、そのスクリプトの範囲で現実的(実際には自動判定とは言えない)
- 最初にマッチした(コアース可能な)メソッド
- プログラマ指定
- メソッド指定
- 型パラメータ(型オブジェクト配列): Reflectionの手法
- 型パラメータ(エンコードした型オブジェクト配列):Rjbの手法
- C++のマングリングもこの方法の一種と考えられる
- 引数指定
- メタデータを持つ引数型(例:Variant)
- 型情報の指定
- メソッド指定
引数による型指定
メタデータを持つ引数型
例)
class Argument def initialize(t, value) @type = t @value = value end attr_accessor :type, :value end ... s = JString.new(Argument.new('[B', 'ABC'))
ブリッジは引数がArgumentクラスのインスタンスであれば、メタデータ(type属性)から型情報を得て、value属性から引数値を得る。type属性で指定された型へのキャストを必要に応じて行う。
長所
インクリメンタルなスクリプトの修正が可能。
開始
v = foo.bar(1, 2, 3)
実行結果からメソッド指定が必要と判断
v = foo.bar(Argument.new('S', 1), 2, 3)
実行結果からさらに指定が必要と判断
v = foo.bar(Argument.new('S', 1), 2, Argument.new('J', 3))
短所
記述時点で呼び出すべきメソッドを特定できているのであれば、メソッド指定法と変わらないと考えられる。
引数リストが長くなるためスクリプトの簡潔さが失われる。
型情報の指定
例
s = JString.new({ :value => 'ABC', :type => '[B' })
ブリッジは引数がハッシュならば、:typeキーから型情報を得て、:valueから引数値を得る。:typeで指定された型へのキャストを必要ならば行う。
長所
特殊なクラス(上記Argumentクラス)や、特殊な記法(Rjbの_invoke)が不要。
短所
引数リストが巨大になる(読みにくいスクリプト)おそれがある。
メタデータを持つ引数型の拡張
例)
class ByteArrayArgument < Argument def initialize(value) super('[B', value) end def value a = [] value.each_byte {|b| a << b } a end end ... s = JString.new(ByteArrayArgument.new('ABC'))
長所
スクリプトは比較的記述しやすい。型によっては、ブリッジ側での実行時の型変換処理が単純化できる(上の例ではStringからバイト配列への変換を型指定クラスに実装している)。
短所
short[]、long[] の判定などが最終的には必要となるため、例で示したような引数クラス自身による変形だけでは完結しない。(これは長所で上げた点に対する短所で、他の方法に比べた場合の短所では無い。他の方法も同様な処理が必要である)
Keyword(s):
References: