Class: RSRuby
Overview
Synopsis
This class represents the embedded R interpreter. The Singleton module is mixed in to ensure that only one R interpreter is running in a script at any one time and that the interpreter can always be easily accessed without using a global variable.
The R interpreter is started by calling RSRuby.instance. The returned object represents the R interpreter and R functions are called by calling methods on this object:
r = RSRuby.instance
r.sum(1,2,3)
puts r.t_test(1,2,3)['p-value']
See the manual for more details on calling functions and the conversion system for passing data between Ruby and R. If no suitable conversion from R to Ruby is found, an RObj is returned (all R functions are returned as instances of RObj). –
Copyright
Copyright © 2006 Alex Gutteridge
The Original Code is the RPy python module.
The Initial Developer of the Original Code is Walter Moreira. Portions created by the Initial Developer are Copyright © 2002 the Initial Developer. All Rights Reserved.
Contributor(s): Gregory R. Warnes <[email protected]> (RPy Maintainer)
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++
Constant Summary collapse
- VERSION =
'0.5.1'
- TOP_CONVERSION =
Constants for conversion modes
4
- PROC_CONVERSION =
4
- CLASS_CONVERSION =
3
- BASIC_CONVERSION =
2
- VECTOR_CONVERSION =
1
- NO_CONVERSION =
0
- NO_DEFAULT =
-1
Instance Attribute Summary collapse
-
#caching ⇒ Object
Returns the value of attribute caching.
-
#class_table ⇒ Object
Returns the value of attribute class_table.
-
#default_mode ⇒ Object
Returns the value of attribute default_mode.
-
#proc_table ⇒ Object
Returns the value of attribute proc_table.
Class Method Summary collapse
-
.convert_args_to_lcall(args) ⇒ Object
Converts an Array of function arguments into lcall format.
-
.convert_method_name(name) ⇒ Object
Converts a String representing a ‘Ruby-style’ R function name into a String with the real R name according to the rules given in the manual.
-
.get_default_mode ⇒ Object
Returns the current default conversion mode as an Integer.
-
.get_rsruby_input ⇒ Object
TODO - not implemented.
-
.get_rsruby_output ⇒ Object
TODO - not implemented.
-
.get_rsruby_showfiles ⇒ Object
TODO - not implemented.
- .img(filename, args = {}) {|r| ... } ⇒ Object
-
.set_default_mode(m) ⇒ Object
Sets the default conversion mode for RSRuby.
-
.set_rsruby_input(m) ⇒ Object
TODO - not implemented.
-
.set_rsruby_output(m) ⇒ Object
TODO - not implemented.
-
.set_rsruby_showfiles(m) ⇒ Object
TODO - not implemented.
Instance Method Summary collapse
-
#[](r_id) ⇒ Object
The same as method_missing, but only returns the R function/object, does not call it.
- #__getitem__(name, init = false) ⇒ Object
- #__init_eval_R__(s) ⇒ Object
-
#crash ⇒ Object
This method is for testing catching of segfaults.
-
#delete_from_cache(x) ⇒ Object
Delete an R object from the cache.
-
#eval_R(s) ⇒ Object
Evaluates the given string in R.
-
#get_fun(name) ⇒ Object
Obtain an R object via its name.
-
#help(*args) ⇒ Object
Wraps the R help function.
-
#initialize ⇒ RSRuby
constructor
Create a new RSRuby interpreter instance.
-
#method_missing(r_id, *args) ⇒ Object
Handles method name conversion and calling of R functions If called without args the R function/varialbe is returned rather than called.
-
#r_init ⇒ Object
Starts the R interpreter.
- #reset_cache ⇒ Object
-
#shutdown ⇒ Object
Shutdown the R interpreter.
-
#with_mode(mode, func) ⇒ Object
Takes an #RObj representing an R function and sets the ‘wrapping’ mode for that function.
Constructor Details
#initialize ⇒ RSRuby
Create a new RSRuby interpreter instance. The Singleton design pattern ensures that only one instance can be running in a script. Further calls to RSRuby.instance will return the original instance.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/rsruby.rb', line 74 def initialize() #Initialize R r_init @default_mode = NO_DEFAULT @class_table = {} @proc_table = {} @caching = true reset_cache #Catch errors self.__init_eval_R__("options(error=expression(NULL))") #disable errors self.__init_eval_R__("options(show.error.messages=F)") end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(r_id, *args) ⇒ Object
Handles method name conversion and calling of R functions If called without args the R function/varialbe is returned rather than called.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/rsruby.rb', line 131 def method_missing(r_id,*args) #Translate Ruby method call to R robj_name = RSRuby.convert_method_name(r_id.to_s) #Retrieve it robj = self.__getitem__(robj_name) #TODO perhaps this is not neccessary - always call these methods #use the [] syntax for variables etc... if args.length > 0 #convert arguments to lcall format lcall_args = RSRuby.convert_args_to_lcall(args) #Return result of calling object with lcall #formatted args return robj.lcall(lcall_args) end return robj end |
Instance Attribute Details
#caching ⇒ Object
Returns the value of attribute caching.
69 70 71 |
# File 'lib/rsruby.rb', line 69 def caching @caching end |
#class_table ⇒ Object
Returns the value of attribute class_table.
69 70 71 |
# File 'lib/rsruby.rb', line 69 def class_table @class_table end |
#default_mode ⇒ Object
Returns the value of attribute default_mode.
69 70 71 |
# File 'lib/rsruby.rb', line 69 def default_mode @default_mode end |
#proc_table ⇒ Object
Returns the value of attribute proc_table.
69 70 71 |
# File 'lib/rsruby.rb', line 69 def proc_table @proc_table end |
Class Method Details
.convert_args_to_lcall(args) ⇒ Object
Converts an Array of function arguments into lcall format. If the last element of the array is a Hash then the contents of the Hash are interpreted as named arguments.
The returned value is an Array of tuples (Arrays of length two). Each tupple corresponds to a name/argument pair.
For example:
convert_args_to_lcall([1,2,3,{:a=>4,:b=>5})
=> [['',1],['',2],['',3],['a',4],['b',5]]
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/rsruby.rb', line 199 def RSRuby.convert_args_to_lcall(args) lcall_args = [] args.each_with_index do |arg,i| unless arg.kind_of?(Hash) and i == args.length-1 lcall_args.push(['',arg]) else arg.each do |k,v| lcall_args.push([k.to_s,v]) end end end return lcall_args end |
.convert_method_name(name) ⇒ Object
Converts a String representing a ‘Ruby-style’ R function name into a String with the real R name according to the rules given in the manual.
180 181 182 183 184 185 186 187 |
# File 'lib/rsruby.rb', line 180 def RSRuby.convert_method_name(name) if name.length > 1 and name[-1].chr == '_' and name[-2].chr != '_' name = name[0..-2] end name.gsub!(/__/,'<-') name.gsub!(/_/, '.') return name end |
.get_default_mode ⇒ Object
Returns the current default conversion mode as an Integer. DEPRECATED: Use the accessor on the RSRuby instance isntead
228 229 230 |
# File 'lib/rsruby.rb', line 228 def RSRuby.get_default_mode RSRuby.instance.default_mode end |
.get_rsruby_input ⇒ Object
TODO - not implemented
238 239 240 |
# File 'lib/rsruby.rb', line 238 def RSRuby.get_rsruby_input @@rsruby_input end |
.get_rsruby_output ⇒ Object
TODO - not implemented
248 249 250 |
# File 'lib/rsruby.rb', line 248 def RSRuby.get_rsruby_output @@rsruby_output end |
.get_rsruby_showfiles ⇒ Object
TODO - not implemented
258 259 260 |
# File 'lib/rsruby.rb', line 258 def RSRuby.get_rsruby_showfiles @@rsruby_showfiles end |
.img(filename, args = {}) {|r| ... } ⇒ Object
119 120 121 122 123 124 125 126 |
# File 'lib/rsruby.rb', line 119 def self.img(filename,args={}) format = File.extname(filename).gsub(".","").to_sym r = RSRuby.instance raise ArgumentError, "Format #{format.to_s} is not supported" unless [:pdf].include? format r.pdf(filename,args) yield(r) r.dev_off.call end |
.set_default_mode(m) ⇒ Object
Sets the default conversion mode for RSRuby. The constants defined in #RSRuby should be used DEPRECATED: Use the accessor instead
220 221 222 223 224 225 |
# File 'lib/rsruby.rb', line 220 def RSRuby.set_default_mode(m) if m < -1 or m > TOP_CONVERSION raise ArgumentError, "Invalid mode requested" end RSRuby.instance.default_mode = m end |
.set_rsruby_input(m) ⇒ Object
TODO - not implemented
233 234 235 |
# File 'lib/rsruby.rb', line 233 def RSRuby.set_rsruby_input(m) @@rsruby_input = m end |
.set_rsruby_output(m) ⇒ Object
TODO - not implemented
243 244 245 |
# File 'lib/rsruby.rb', line 243 def RSRuby.set_rsruby_output(m) @@rsruby_output = m end |
.set_rsruby_showfiles(m) ⇒ Object
TODO - not implemented
253 254 255 |
# File 'lib/rsruby.rb', line 253 def RSRuby.set_rsruby_showfiles(m) @@rsruby_showfiles = m end |
Instance Method Details
#[](r_id) ⇒ Object
The same as method_missing, but only returns the R function/object, does not call it.
158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/rsruby.rb', line 158 def [](r_id) #Translate Ruby method call to R robj_name = RSRuby.convert_method_name(r_id.to_s) #Retrieve it robj = self.__getitem__(robj_name) #And return it return robj end |
#__getitem__(name, init = false) ⇒ Object
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/rsruby.rb', line 280 def __getitem__(name,init=false) #Find the identifier and cache (unless already cached) unless @cache.has_key?(name) && @caching if init robj = @cache['get'].__init_lcall__([['',name]]) else robj = @cache['get'].lcall([['',name]]) end @cache[name] = robj if @caching end #Retrieve object from cache robj ||= @cache[name] return robj end |
#__init_eval_R__(s) ⇒ Object
275 276 277 278 |
# File 'lib/rsruby.rb', line 275 def __init_eval_R__(s) parsed = self.parse.__init_lcall__([['text',s]]) self.eval.__init_lcall__([['',parsed]]) end |
#crash ⇒ Object
This method is for testing catching of segfaults
154 155 156 157 158 |
# File 'ext/rsruby.c', line 154
VALUE crash(){
int* ptr = (int*)0;
*ptr = 1;
return Qtrue;
}
|
#delete_from_cache(x) ⇒ Object
Delete an R object from the cache. Use R-style function naming, not ruby style.
115 116 117 |
# File 'lib/rsruby.rb', line 115 def delete_from_cache(x) @cache.delete(x) end |
#eval_R(s) ⇒ Object
Evaluates the given string in R. Returns the result of the evaluation.
263 264 265 |
# File 'lib/rsruby.rb', line 263 def eval_R(s) self.eval(self.parse(:text => s)) end |
#get_fun(name) ⇒ Object
Obtain an R object via its name. This is only used to get the ‘get’ function. All subsequent calls go via the ‘get’ function itself
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'ext/rsruby.c', line 69
VALUE get_fun(VALUE self, VALUE name){
VALUE str;
int conversion=TOP_MODE;
SEXP robj;
VALUE rubyobj;
char* cstr_name;
str = StringValue(name);
cstr_name = RSTRING_PTR(str);
robj = (SEXP)get_fun_from_name(cstr_name);
if (!robj)
return Qnil;
/* Wrap the returned R object as a ruby Object */
rubyobj = Data_Wrap_Struct(rb_const_get(rb_cObject,
rb_intern("RObj")), 0, 0, robj);
rb_iv_set(rubyobj,"@conversion",INT2FIX(conversion));
rb_iv_set(rubyobj,"@wrap",Qfalse);
return rubyobj;
}
|
#help(*args) ⇒ Object
Wraps the R help function.
269 270 271 272 |
# File 'lib/rsruby.rb', line 269 def help(*args) helpobj = @cache['helpfun'].call(args) self.print(helpobj) end |
#r_init ⇒ Object
Starts the R interpreter.
129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'ext/rsruby.c', line 129
VALUE rr_init(VALUE self){
SEXP R_References;
init_R(0,NULL);
// Initialize the list of protected objects
R_References = R_NilValue;
SET_SYMVALUE(install("R.References"), R_References);
return self;
}
|
#reset_cache ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/rsruby.rb', line 94 def reset_cache #Setup R object cache @cache = {} @cache['get'] = self.get_fun('get') #Get constants @cache['TRUE'] = self.__getitem__('T',true) @cache['FALSE'] = self.__getitem__('F',true) @cache['parse'] = self.__getitem__('parse',true) @cache['eval'] = self.__getitem__('eval',true) @cache['NA'] = self.__init_eval_R__('NA') @cache['NaN'] = self.__init_eval_R__('NaN') # @cache['NAN'] = self.eval_R('as.double(NA)') #help! @cache['helpfun'] = self.with_mode(NO_CONVERSION, self.__getitem__('help',true)) end |
#shutdown ⇒ Object
Shutdown the R interpreter
118 119 120 121 122 123 124 |
# File 'ext/rsruby.c', line 118 VALUE rs_shutdown(VALUE self){ r_finalize(); Rf_endEmbeddedR(0); return Qtrue; } |
#with_mode(mode, func) ⇒ Object
Takes an #RObj representing an R function and sets the ‘wrapping’ mode for that function. Implemented for compatibility with RPy.
173 174 175 176 |
# File 'lib/rsruby.rb', line 173 def with_mode(mode,func) func.wrap = mode return func end |