Create  Edit  Diff  FrontPage  Index  Search  Changes  Login

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[] の判定などが最終的には必要となるため、例で示したような引数クラス自身による変形だけでは完結しない。(これは長所で上げた点に対する短所で、他の方法に比べた場合の短所では無い。他の方法も同様な処理が必要である)

Last modified:2007/05/14 09:57:14
Keyword(s):
References: