R4rb 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,208 @@
1
+ # encoding: utf-8
2
+ ### IMPORTANT, no use of R4rb tools! R2rb or Rserve mode only!
3
+
4
+ module Rserve
5
+
6
+ ## server side
7
+ def Rserve.pid
8
+ `ps -C Rserve -o pid=`.strip
9
+ end
10
+
11
+ def Rserve.running?
12
+ !Rserve.pid.empty?
13
+ end
14
+
15
+ def Rserve.start(rserve=File.expand_path("~/bin/Rserv"))
16
+ `R CMD #{rserve}` unless Rserve.running?
17
+ end
18
+
19
+
20
+ def Rserve.stop
21
+ pid=Rserve.pid
22
+ `kill #{pid}` unless pid.empty?
23
+ sleep(2)
24
+ if Rserve.running?
25
+ puts "Sorry! but the Rserver is still running!"
26
+ end
27
+ end
28
+
29
+ ## client side
30
+ @@clients,@@cli=nil,nil
31
+
32
+ def Rserve.init
33
+ #puts "Rserve.init"
34
+ Array.initR
35
+ #puts "Rserve.init2"
36
+ "require(Rserve)".R2rb
37
+ #puts "Rserve.init3"
38
+ @@clients,@@cli=[],nil
39
+ @@out=[]
40
+ @@out.rb2R=R2rb
41
+ #puts "Rserve.init4"
42
+ end
43
+
44
+ #####################################################
45
+ # the two following methods to be possibly redefined
46
+ # in particular inside Dyndoc to automatically
47
+ # allocate the R session related to the user!
48
+ def Rserve.cli
49
+ @@cli
50
+ end
51
+ #
52
+ def Rserve.cli=(cli)
53
+ @@cli=cli
54
+ end
55
+ #####################################################
56
+
57
+
58
+ def Rserve.client(cli=nil)
59
+ ## automate the init process!
60
+ #Rserve.init unless @@clients
61
+
62
+ ##return current client!
63
+ unless cli
64
+ return Rserve.cli
65
+ ## create a new client
66
+ else
67
+ Rserve.open(cli)
68
+ end
69
+ end
70
+
71
+ ## change the current client!
72
+ def Rserve.client=(cli=nil)
73
+ return nil unless @@clients.include? cli
74
+ Rserve.cli=cli
75
+ end
76
+
77
+ def Rserve.open(cli)
78
+ "#{cli.to_s} <- RSconnect()".R2rb
79
+ @@clients << cli
80
+ Rserve.cli=cli
81
+ end
82
+
83
+ def Rserve.close(cli=nil)
84
+ cli=Rserve.cli unless cli
85
+ return unless @@clients.include? cli
86
+ "RSclose(#{cli.to_s})".R2rb
87
+ @@clients.delete(cli)
88
+ end
89
+
90
+ def Rserve.ls
91
+ @@clients
92
+ end
93
+
94
+ #####################################################
95
+ ## interface
96
+ def Rserve.complete_code!(code)
97
+ code.gsub!("\\","\\\\")
98
+ code.gsub!("\"","\\\"")
99
+ code.replace("RSeval(#{cli},\"capture.output({"+code+"})\")")
100
+ end
101
+
102
+
103
+ def Rserve.completed_code(code,capture=true)
104
+ open,close= (capture ? ["capture.output({","})"] : ["",""])
105
+ "RSeval(#{cli},\""+open+code.gsub("\\","\\\\").gsub("\"","\\\"")+close+"\")"
106
+ end
107
+
108
+ def Rserve.eval(code,cli=nil)
109
+ cli=Rserve.cli unless cli
110
+ return nil unless cli
111
+ ## check parsing locally (without RSeval)
112
+ status=R2rb.parse code
113
+ if status!=1
114
+ R2rb.parse code,true
115
+ return false
116
+ end
117
+ ## RSeval completed in code!
118
+ Rserve.complete_code!(code)
119
+ #puts "Rserve.eval:";p code
120
+ R2rb.eval code
121
+ #@@out < code ##@@out.inR2rb code # since @@out < code but for R2rb
122
+ end
123
+
124
+ def Rserve.try_eval(code,cli=nil)
125
+ cli=Rserve.cli unless cli
126
+ try_code=".result_try_code<-try({\n"+code+"\n},silent=TRUE)\n"
127
+ puts Rserve.output(try_code,cli).join("\n")
128
+ puts R2rb.output(Rserve.completed_code(".result_try_code",false)) if "inherits(.result_try_code,'try-error')".to_R
129
+ end
130
+
131
+ def Rserve.<<(code)
132
+ Rserve.eval(code)
133
+ end
134
+
135
+ def Rserve.output(code,cli=nil)
136
+ #puts "Rserve.output:";p code
137
+ cli=Rserve.cli unless cli
138
+ return nil unless cli
139
+ ## RSeval completed in code!
140
+ Rserve.complete_code!(code)
141
+ @@out < code ##@@out.inR2rb rcode.to_s
142
+ return (@@out.length<=1 ? @@out[0] : @@out)
143
+ end
144
+
145
+ def Rserve.<(code)
146
+ Rserve.output(code)
147
+ end
148
+
149
+ def Rserve.assign(code,var=nil,cli=nil)
150
+ code+=",quote(#{var})" if var
151
+ cli=Rserve.cli unless cli
152
+ code="RSassign(#{cli},#{code})"
153
+ #p code
154
+ #R2rb << code ###????
155
+ Rserve << code
156
+ end
157
+
158
+ class RVector < R2rb::RVector
159
+
160
+ def RVector.assign(var,ary,cli=nil)
161
+ super(var,ary)
162
+ Rserve.assign(var,var,cli)
163
+ end
164
+
165
+ attr_accessor :cli
166
+
167
+ ## The goal is to connect a ruby Array to a Rserve Vector
168
+ def initialize(name,cli=nil)
169
+ @cli=(cli ? cli : Rserve.cli)
170
+ puts "WARNING: Rserve::RVector.initialize: @cli is null!" unless @cli
171
+ @name_orig=name
172
+ super(name!)
173
+ @type="expr"
174
+ end
175
+
176
+ def name! #name from cli and name_orig
177
+ ##puts "name!";p @name_orig
178
+ ##deb,fin="quote(",")" #(@name_orig=~/^evalq\(/ ? ["quote(",")"] : ["\"","\""])
179
+ "RSeval(#{@cli},quote(#{@name_orig}))"
180
+ end
181
+
182
+ def <<(name)
183
+ ## no "var" in this context! transform it in String if necessary
184
+ @name_orig=name.to_s
185
+ super(name!)
186
+ return self
187
+ end
188
+
189
+ ## no need to make aby change for ">"
190
+
191
+ def <(ary)
192
+ ary.R2rb(".rubyExport") #transition
193
+ Rserve.assign(".rubyExport",@name_orig,@cli)
194
+ end
195
+
196
+ alias value= <
197
+
198
+ def set_with_arg(ary)
199
+ ary=[ary] unless ary.is_a? Array
200
+ ary.R2rb(".rubyExport") #transition
201
+ #p @name_orig+@arg
202
+ Rserve.assign(".rubyExport",@name_orig+@arg,@cli)
203
+ end
204
+
205
+ alias value_with_arg= set_with_arg
206
+
207
+ end
208
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ class String
3
+
4
+ def to_aRy(sep=",")
5
+ self.split(sep).map{|str|
6
+ R2rb.multilang_parser(str)
7
+ }.flatten
8
+ end
9
+
10
+ end
11
+
12
+ module R2rb
13
+
14
+ @@pair=["<<",">>"]
15
+
16
+ def R2rb.pair
17
+ @@pair
18
+ end
19
+
20
+ def R2rb.pair=(pair)
21
+ if pair.is_a? String
22
+ pairs={"{"=>"}","("=>")","<"=>">","["=>"]"}
23
+ pair2=pair.reverse.gsub(/[#{Regexp.escape(pairs.keys.join)}]/) {|e| Regexp.escape(pairs[e])}
24
+ pair=[pair,pair2]
25
+ end
26
+ #p "ICI";p pair
27
+ if (pair.is_a? Array) and pair.length==2
28
+ @@pair=pair
29
+ end
30
+ #p @@pair
31
+ end
32
+
33
+ def R2rb.multilang_parser(str)
34
+ #p @@pair
35
+ lang="r|R|rb|Rb"
36
+ s=str
37
+ if @@pair[0].empty?
38
+ mask = /((?:#{lang}).*)/
39
+ else
40
+ mask = /#{Regexp.escape(@@pair[0])}((?:#{lang})[^#{Regexp.escape(@@pair[0])}]*)#{Regexp.escape(@@pair[1])}/
41
+ end
42
+ str=str.split(mask,-1)
43
+ return s if str.length<=1
44
+ vals=[]
45
+ res=[]
46
+ inds=0..(str.length / 2 - 1)
47
+ ".tmp<-NULL".to_R
48
+ inds.each {|i|
49
+ res << str[2*i]
50
+ if str[2*i+1] =~ /^(?:r|R):(.*)/
51
+ (".tmp<-cbind(.tmp,"+$1+")").to_R
52
+ end
53
+ if str[2*i+1] =~ /^(?:rb|Rb):(.*)/
54
+ a=eval($1)
55
+ a=[a] unless a.is_a? Array
56
+ a > :tmp
57
+ (".tmp<-cbind(.tmp,tmp)").to_R
58
+ end
59
+ }
60
+ res << str[-1]
61
+ #p res
62
+ cmd="apply(.tmp,1,function(e) paste("
63
+ inds.each{|i| cmd += "'"+res[i]+"',e["+i.to_s+"+1]," }
64
+ cmd += "'"+res[-1]+"',sep=''))"
65
+ #"print(.tmp)".to_R
66
+ #p cmd
67
+ cmd.to_R
68
+ end
69
+ end
@@ -0,0 +1,127 @@
1
+ ## Attention "...\n..." have to be replaced by "...\\n..."
2
+ ## example : 'cat("toto\n")' fails but not 'cat("toto\\n")'
3
+ ## more surprisingly, this fails even in comment '# cat("toto\n")'
4
+
5
+ module R2rb
6
+
7
+ def R2rb.init(args=["--save","--slave","--quiet"])
8
+ @@initR=R2rb.initR(args) unless R2rb.alive?
9
+ end
10
+
11
+ def R2rb.alive?
12
+ defined? @@initR
13
+ end
14
+
15
+ class RBuffer
16
+ def initialize
17
+ @s=String.new
18
+ end
19
+
20
+ def init
21
+ R2rb.init
22
+ end
23
+
24
+ def clear
25
+ @s=""
26
+ end
27
+
28
+ def +(s=nil)
29
+ if s
30
+ s=s.to_s unless s.is_a? String
31
+ @s += "\n"+s
32
+ else
33
+ clear
34
+ end
35
+ return self
36
+ end
37
+
38
+ def exec(aff=nil)
39
+ R2rb.eval @s,aff
40
+ end
41
+ end
42
+
43
+ =begin
44
+ class RVector
45
+ def <<(name)
46
+ if name.is_a? Symbol
47
+ @name=name.to_s
48
+ @type="var"
49
+ else
50
+ @name=name
51
+ @type="expr"
52
+ end
53
+ return self
54
+ end
55
+
56
+ def >(arr)
57
+ arr.replace(self.get)
58
+ return self
59
+ end
60
+ end
61
+ =end
62
+
63
+ class RConsole
64
+ def initialize
65
+ require "readline"
66
+ end
67
+
68
+ def init args
69
+ R2rb.init args
70
+ end
71
+
72
+ def exec
73
+ #todo : continuation
74
+ toggle=true
75
+ fin=false
76
+ words=[]
77
+ rvect=R2rb::RVector.new("")
78
+ Readline.completion_proc=Proc.new {|e|
79
+ cpt=0
80
+ begin
81
+ begin
82
+ cpt += 1
83
+ toggle = !toggle
84
+ rvect << (toggle ? "apropos(" : "ls(pat=")+"'^"+e+"')" > words
85
+ res=words.map{|w| w[Regexp.new("^"+e+".*")]}-[nil]
86
+ end while res.empty? and cpt<3
87
+ res
88
+ rescue
89
+ warn("\r"+e+" not suitable for completion!!!")
90
+ []
91
+ end
92
+ }
93
+ Readline.completion_append_character=""
94
+ begin
95
+ line = Readline.readline("R> ", true)
96
+ if !(fin = line=="quit")
97
+ R2rb.eval line,true
98
+ toggle=true
99
+ end
100
+ end until fin
101
+ end
102
+ end
103
+ end
104
+
105
+ def find_installed_R
106
+
107
+ if RUBY_PLATFORM=~/mingw32/
108
+ ENV["R_HOME"]=`R RHOME`
109
+ elsif RUBY_PLATFORM=~/darwin/
110
+ ENV["R_HOME"]=`R RHOME`.strip
111
+ else
112
+ dirs=["/usr/lib/R","/usr/local/lib/R","/usr/lib64/R","/usr/local/lib64/R"]
113
+
114
+ dirs.each do |dir|
115
+ if FileTest.exists?(dir)
116
+ return dir
117
+ end
118
+ end
119
+
120
+ raise RuntimeError, "couldn't find R Home : R seems to be uninstalled!!"
121
+ end
122
+
123
+ end
124
+
125
+ ENV["R_HOME"]=`R RHOME`.strip.split("\n").select{|l| l=~/^\//}[0] unless `R RHOME`.empty?
126
+
127
+ ENV["R_HOME"]=find_installed_R unless ENV["R_HOME"]
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ module RObj
3
+
4
+ def RObj.<(rcode)
5
+ return (R2rb < rcode)
6
+ end
7
+
8
+ def RObj.class(rname)
9
+ RObj < "class(#{rname})"
10
+ end
11
+
12
+ def RObj.mode(rcode)
13
+ RObj < "mode(#{rcode})"
14
+ end
15
+
16
+ # temporary R object saved in ruby object!
17
+ def RObj.make(rcode,first=true)
18
+ mode=RObj.mode(rcode)
19
+ RObj < ".tmpRObj<-(#{rcode})" if first
20
+ code=(first ? ".tmpRObj" : rcode.dup)
21
+ if ['numeric','logical','complex','character'].include?(mode)
22
+ #if RObj.class(code)=="matrix"
23
+ return (RObj< rcode)
24
+ elsif mode=="list"
25
+ robj={}
26
+ tmpNames=RObj < "names(#{rcode})"
27
+ tmpNames.each_with_index do |nam,i|
28
+ key=(nam.empty? ? i : nam)
29
+ rkey=(nam.empty? ? i : "\""+nam+"\"")
30
+ robj[key]=RObj.make("#{rcode}[[#{rkey}]]",false)
31
+ end
32
+ return robj
33
+ else
34
+ return nil
35
+ end
36
+ end
37
+
38
+ def RObj.<<(rcode)
39
+ RObj.make(rcode)
40
+ end
41
+
42
+ def RObj.exist?(rname)
43
+ RObj < "exists(\"#{rname}\")"
44
+ end
45
+
46
+ end