2010年09月06日 Rでsocket
_ rsrubyとsocket
以前、Rをrubyから使うためにrsrubyを使ったことがある。しかし、debianのバージョンが上がったときに、うまくインストールできなくなったので、使うのを止めてしまった。しかし、もっと単純にrubyからRを使う方法を発見した。
Rの関数を調べていたら、socketConnectionというものを発見した。socketの読み書きをするためのものらしい。これを使えば、rubyと通信できるのではということで試してみた。
まずは、rubyをserverにして、Rをclientにする場合として、次のようなコードを書いた。まずはR側。
sock<-socketConnection(host = "localhost", 12343) repeat{ write("Hello, R server.",sock) str<-readLines(sock,1) eval(parse(text=str)) }
そして、ruby側。
require 'socket' require 'thread' s=TCPServer.new(12343) Thread.start(s.accept){|cl| begin i=0 cl.each{|cmd| puts cmd cl.puts "plot(%d:%d,%d:%d)"%[i,i+10,i+10,i+20] i+=1 } ensure cl.close end } while true
Rで待ちを入れる関数を知らないので、ひたすらグラフを更新するが、一応うまく動く。次は逆にrubyをclientにして、Rをserverにする場合。Rでserverの処理を書くのは面倒かとも思ったが、意外に短くかける。
sock<-socketConnection(host = "localhost", 12343 ,server=TRUE) repeat{ cmd<-readLines(sock,1) eval(parse(text=cmd)) }
そして、rubyのclient。
require 'socket' s=TCPSocket.open('localhost',12343) i=0 loop{ s.puts("plot(%d:%d,%d:%d)"%[i,i+10,i+20,i+30]) i+=1 sleep 5 }
Rのサーバーは命令を実行しても応答が帰って来ないが、clientが接続すると返ってくる。おそらくsingle connectionで、だからコードも短くかけるのだろう。
これで、Rとrubyをソケットでつないで、命令を実行できることが実証された。Rの実行結果を文字列で戻して、それをrubyで解釈すれば、実行結果を返すこともできるだろう。rsrubyの代わりに使おうと思えば、使える気がする。
しかし、問題はある。これはrsrubyも同じなのだが、plotで書いたグラフは、制御を奪われている間は更新されないようで、その上を別のwindowが通過すると、消えてしまう。これを回避する手段はないかな。