7526


はじめまして、VisualBasic.net(4.0),Windows7上のアプリケーションからRの操作を試みています。

Rとの接続にはCodePlex上で公開されているR.NET(<https://rdotnet.codeplex.com/>)を使用しています。（※その後R.NETの公開は<https://github.com/rdotnet/rdotnet>に移っています。）

※まずテストの為以下のようなコードを実行しました。

[code]

    Imports RDotNet
    Module Module1
    
        Sub Main()
            Dim engine = REngine.GetInstance()
            Dim obj2 As RDotNet.Closure
            obj2 = engine.Evaluate("cat").AsFunction
        End Sub
    
    End Module
    
[/code]

これを実行するとRDotNet.Closure型の変数obj2にはRのコンソール上単にcat入力した場合の結果、つまり関数catの情報が格納されているはずだと考えています。

※次に例としてRコンソール上でcatを実行した結果を提示します。

[code]

    > cat
    function (..., file = "", sep = " ", fill = FALSE, labels = NULL, 
        append = FALSE) 
    {
        if (is.character(file)) 
            if (file == "") 
                file <- stdout()
            else if (substring(file, 1L, 1L) == "|") {
                file <- pipe(substring(file, 2L), "w")
                on.exit(close(file))
            }
            else {
                file <- file(file, ifelse(append, "a", "w"))
                on.exit(close(file))
            }
        .Internal(cat(list(...), file, sep, fill, labels, append))
    }
    <bytecode: 0x000000000a862060>
    <environment: namespace:base>
    >
    
[/code]

※そしてサンプルコードの実行時のVisualStudioでClosureのウォッチ式の結果を提示します。

![Closureクラスのウォッチ式](https://i.stack.imgur.com/mhvxo.jpg)

引数の情報つまりFunctionの（）内の部分に関してはClosureクラスのArgumentsプロパティにペア・リストの形で格納されておりFor
eachで取り出すことが出来ました。

しかしそれ以降の関数本体の定義部分がClosureクラスのどこに格納されているのかわかりません。

ClosureクラスにはBodyプロパティがありましたが型がバイトコードになっていてよくわかりませんでした。

どなたか関数の本体部分の格納箇所が分かる方、もしくはこういった場合VisualStudio上（2010）で確認方法をご存知の方がおられましたらお助け出来ませんでしょうか？

よろしくお願いします。


CC BY-SA 4.0
2015-03-06T01:45:06.790
7513
2021-05-02T11:47:04.847
2021-05-02T11:47:04.847
19110
8715
question
visual-studio r vb.net rdotnet
R.NET、クロージャー型の展開について


`cat`はバイトコンパイルされているので、そもそも`R`で

[code]

    > cat
    
[/code]

とした時にみえる定義は以下の`PrintLanguageEtc`が出力しているものです。

r-source/print.c at 52c467ea1c4493abe2d1e3483fd0658873a0c629 · wch/r-source  
<https://github.com/wch/r-source/blob/52c467ea1c4493abe2d1e3483fd0658873a0c629/src/main/print.c#L189>

`RDotNet`の実装を細かく追ったわけではないのですが、こちらも上記関数と同様に`SEXP`を扱うようなのでおそらく`cat`の関数定義自体は`RDotNet`側では保持していないでしょう。(式の評価は`R`側に投げるでしょうから)

ではどうするかという点ですが2点思いつきました。

### 1. コンソール出力を文字列に吐かせる

[code]

    engine.Evaluate("print(cat)")
    
[/code]

とした時、コンソール出力に`R`コンソールでの出力結果が表示されるかと思います。そこでコンソールのデフォルト出力を変更します。

[code]

    Using sw As New System.IO.StringWriter()
        Dim out = Console.Out()
        Console.SetOut(sw)
        engine.Evaluate("print(cat)")
        Dim str = sw.ToString() 'ここに出力が格納されます
        Console.SetOut(out)
    End Using
    
[/code]

### 2. なんとかR側で文字列を出力させる

[code]

    Dim arr = engine.Evaluate("as.character(functionBody(cat))").AsCharacter
    
[/code]

とすると、`{`以降(引数部分は取得できない)については`arr`に文字列配列(`R`ではベクトル)で格納されます。最終行の`}`が取得できないようで、完璧な解法にはならないかもしれません。

他に良い関数などがあれば私も知りたいです。


CC BY-SA 3.0
2015-03-06T04:07:53.090
7526
2015-03-06T05:23:33.340
2015-03-06T05:23:33.340
3313
3313
7513
answer