相互運用性
GraalVMでは、JavaScript、Ruby、Pythonや、LLVMビットコードにコンパイルされるものを含め、他の様々なプログラミング言語がサポートされています。GraalVMのRランタイムではプログラミング言語の相互運用性を確保するためのAPIが提供され、これを使用することで、GraalVMでサポートされている他の言語からコードを実行できます。他の言語にアクセスするには、--polyglot
を指定してRスクリプトを開始する必要があります。
GraalVMのRランタイムでは、次の相互運用性プリミティブを使用できます:
eval.polyglot('languageId', 'code')
では、他の言語のコードを評価します。languageId
にはjs
などを指定できます。eval.polyglot(path = '/path/to/file.extension')
では、ファイルからロードされたコードを評価します。言語は拡張子から認識されます。export('polyglot-value-name', rObject)
では、Rオブジェクトをエクスポートして、他の言語がそれをインポートできるようにします。import('exported-polyglot-value-name')
では、他の言語によってエクスポートされたポリグロット値をインポートします。
さらに学習するには、?functionName
構文を使用します。次の例は、相互運用性機能を示しています:
# get an array from Ruby
x <- eval.polyglot('ruby', '[1,2,3]')
print(x[[1]])
# [1] 1
# get a JavaScript object
x <- eval.polyglot(path='r_example.js')
print(x$a)
# [1] "value"
# use R vector in JavaScript
export('robj', c(1,2,3))
eval.polyglot('js', paste0(
'rvalue = Polyglot.import("robj"); ',
'console.log("JavaScript: " + rvalue.length);'))
# JavaScript: 3
# NULL -- the return value of eval.polyglot
(r_example.jsを使用しています。)
Rベクターは、配列として他の言語に渡されます。これには、42L
やNA
など、単一要素ベクターが含まれます。ただし、NA
を含まない単一要素ベクターは通常、他の言語がスカラー値を必要とする場所で使用できます。配列の添字または同様の操作を他の言語で使用して、Rベクターの個々の要素にアクセスできます。ベクターの要素がNA
でない場合、実際の値はスカラー値(int
など)として返されます。要素がNA
である場合は、null
のような特殊なオブジェクトが返されます。次のRubyコードでこれを示します:
vec = Polyglot.eval("R", "c(NA, 42)")
p vec[0].nil?
# true
p vec[1]
# 42
vec = Polyglot.eval("R", "42")
p vec.to_s
# "[42]"
p vec[0]
# 42
Rに渡された外部オブジェクトは、暗黙的に特定のR型として扱われます。次の表に、いくつかの例を示します。
外部オブジェクトの例(Java) | R側における表示 |
---|---|
int[] {1,2,3} | c(1L,2L,3L) |
int[][] { {1, 2, 3}, {1, 2, 3} } | matrix(c(1:3,1:3),nrow=3) |
int[][] { {1, 2, 3}, {1, 3} } | サポートされていません: エラーが発生します |
Object[] {1, ‘a’, ‘1’} | list(1L, ‘a’, ‘1’) |
42 | 42L |
次の例では、Ruby配列をR組込み関数sum
に簡単に渡すことができます。これは、整数ベクターであるかのようにRuby配列を操作します。
sum(eval.polyglot('ruby', '[1,2,3]'))
外部オブジェクトを明示的にアダプタにラップして、目的のR型に見えるようにすることもできます。このような場合、可能であればデータのコピーは行われません。次のコード・スニペットは、最も一般的なユースケースを示しています:
# gives list instead of an integer vector
as.list(eval.polyglot('ruby', '[1,2,3]'))
# assume the following Java code:
# public class ClassWithArrays {
# public boolean[] b = {true, false, true};
# public int[] i = {1, 2, 3};
# }
x <- new('ClassWithArrays'); # see Java interop below
as.list(x)
# gives: list(c(T,F,T), c(1L,2L,3L))
詳細は、暗黙的および明示的な外部オブジェクト変換の実行可能ファイル仕様を参照してください。
ノート: (R
スクリプトを介してではなく)他の言語またはJavaから開始されたRコンテキストは、Rscript
と同様に、非対話型モードにデフォルト設定されます。これは、コンソール出力(結果がエコーされない)およびグラフィック(出力がウィンドウではなくファイルにデフォルト設定される)に影響し、一部のパッケージは非対話型モードで異なる動作をすることがあります。
相互運用性に関する使用可能なR組込み関数のリストを次にします。詳細は、R --help
のメッセージを参照し、次の例を試してみてください:
> help(java.type)
> ?java.type
> example(java.type)
java.type
java.addToClasspath
is.polyglot.value
eval.polyglot
export
import
他のプログラミング言語との相互運用性の詳細は、『Polyglot Programming』リファレンスを参照してください。