Class: Rri::Engine
- Inherits:
-
Object
- Object
- Rri::Engine
- Defined in:
- lib/rri/engine.rb
Overview
The main class to interface with R
Engine internally holds an instance of the java class JRIEngine which is used for all interaction with R. On top of this it provides a few abstractions to easily convert between ruby and R types.
The main methods of the high level API are #eval_and_convert and #convert_and_assign. The high level API converts to/from R/ruby using a type conversion system described in the README.
It also provides a couple of helper methods just to make the users life easier when working with the lower level java API, most notably #simple_eval and #simple_assign. These functions do not convert values but instead work with references to R objects and are preferred when you don't really care about converting to/from ruby (e.g. intermediate steps of calculations and similar)
Apart from the methods on this ruby class the user can also use any other method on JRIEngine, it will be forwarded via #method_missing.
Constant Summary collapse
- DEFAULT_ENGINE_OPTIONS =
Default options used when creating an engine
{ :r_arguments => ["--no-save"], :callback_object => nil, :run_repl => false }
Class Method Summary collapse
-
.add_r_converter(converter) ⇒ Array
Add a custom converter used to convert ruby objects to R objects.
-
.add_ruby_converter(converter) ⇒ Array
Add a custom converter used to convert R objects to ruby objects.
-
.clear_r_converters ⇒ Object
Clear all class level custom R converters.
-
.clear_ruby_converters ⇒ Object
Clear all class level custom ruby converters.
-
.default_r_converters ⇒ Array
Get default converters to convert ruby objects to R objects.
-
.default_ruby_converters ⇒ Array
Get default converters to convert R objects to ruby objects.
-
.finalize(engine) ⇒ Proc
Helper to make sure all engines are finalized so the R thread dies as it should.
-
.r_converters ⇒ Array
Get all class level custom converters to convert ruby objects to R objects.
-
.ruby_converters ⇒ Array
Get all class level custom converters to convert R objects to ruby objects.
Instance Method Summary collapse
-
#add_r_converter(converter) ⇒ Array
Add a custom converter used to convert ruby objects to R objects.
-
#add_ruby_converter(converter) ⇒ Array
Add a custom converter used to convert R objects to ruby objects.
-
#clear_r_converters ⇒ Object
Clear all instance level custom R converters.
-
#clear_ruby_converters ⇒ Object
Clear all instance level custom R converters.
-
#convert_and_assign(obj, symbol) ⇒ nil
Convert a ruby value to an R type and assign it to an R variable.
-
#convert_to_r_object(obj) ⇒ Array
Convert a ruby object to a R object.
-
#convert_to_ruby_object(rexp) ⇒ Array
Convert an R object to a ruby object.
-
#eval_and_convert(expression) ⇒ Object
Eval expression and convert result to the corresponding ruby type.
-
#get_and_convert(symbol) ⇒ Object
Get a variable from R and convert it to a ruby object.
-
#initialize(options = {}) ⇒ Engine
constructor
Create a new instance of Engine.
-
#method_missing(method, *args, &block) ⇒ Object
Forward any method calls not recognized to JRIEngine.
-
#r_converters ⇒ Array
Get all instance level custom converters to convert ruby objects to R objects.
-
#ruby_converters ⇒ Array
Get all instance level custom converters to convert R objects to ruby objects.
-
#simple_assign(symbol, rexp) ⇒ nil
Helper method to assign expressions to R variables.
-
#simple_eval(expression) ⇒ REXPReference
Helper method to evaluate expressions but avoid any R-to-ruby conversions.
-
#simple_get(symbol) ⇒ REXPReference
Helper method to get a variable from R.
Constructor Details
#initialize(options = {}) ⇒ Engine
Create a new instance of Engine
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/rri/engine.rb', line 119 def initialize( = {}) = DEFAULT_ENGINE_OPTIONS.merge() @engine = Jri::JRIEngine.new([:r_arguments].to_java(:string), [:callback_object], [:run_repl]) # the R thread wont die unless we call #close on @engine, so make sure this # happens when this object is finalized. ObjectSpace.define_finalizer(self, self.class.finalize(@engine)) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Forward any method calls not recognized to JRIEngine
132 133 134 135 136 137 138 |
# File 'lib/rri/engine.rb', line 132 def method_missing(method, *args, &block) if @engine.respond_to? method @engine.send(method, *args, &block) else super end end |
Class Method Details
.add_r_converter(converter) ⇒ Array
Add a custom converter used to convert ruby objects to R objects
38 39 40 41 |
# File 'lib/rri/engine.rb', line 38 def self.add_r_converter(converter) @@r_converters ||= [] @@r_converters << converter end |
.add_ruby_converter(converter) ⇒ Array
Add a custom converter used to convert R objects to ruby objects
75 76 77 78 |
# File 'lib/rri/engine.rb', line 75 def self.add_ruby_converter(converter) @@ruby_converters ||= [] @@ruby_converters << converter end |
.clear_r_converters ⇒ Object
Clear all class level custom R converters
55 56 57 |
# File 'lib/rri/engine.rb', line 55 def self.clear_r_converters @@r_converters = [] end |
.clear_ruby_converters ⇒ Object
Clear all class level custom ruby converters
92 93 94 |
# File 'lib/rri/engine.rb', line 92 def self.clear_ruby_converters @@ruby_converters = [] end |
.default_r_converters ⇒ Array
Get default converters to convert ruby objects to R objects
62 63 64 65 66 67 68 69 |
# File 'lib/rri/engine.rb', line 62 def self.default_r_converters [ RConverters::FloatConverter.new, RConverters::IntegerConverter.new, RConverters::StringConverter.new, RConverters::ArrayConverter.new ] end |
.default_ruby_converters ⇒ Array
Get default converters to convert R objects to ruby objects
99 100 101 102 103 104 105 |
# File 'lib/rri/engine.rb', line 99 def self.default_ruby_converters [ RubyConverters::DoubleConverter.new, RubyConverters::IntegerConverter.new, #RubyConverters::StringConverter.new, ] end |
.finalize(engine) ⇒ Proc
Helper to make sure all engines are finalized so the R thread dies as it should
111 112 113 |
# File 'lib/rri/engine.rb', line 111 def self.finalize(engine) proc { engine.close } end |
.r_converters ⇒ Array
Get all class level custom converters to convert ruby objects to R objects
Converters are returned in the reversed order to how they were added (i.e. the last added is applied first)
49 50 51 52 |
# File 'lib/rri/engine.rb', line 49 def self.r_converters @@r_converters ||= [] @@r_converters.reverse end |
.ruby_converters ⇒ Array
Get all class level custom converters to convert R objects to ruby objects
Converters are returned in the reversed order to how they were added (i.e. the last added is applied first)
86 87 88 89 |
# File 'lib/rri/engine.rb', line 86 def self.ruby_converters @@ruby_converters ||= [] @@ruby_converters.reverse end |
Instance Method Details
#add_r_converter(converter) ⇒ Array
Add a custom converter used to convert ruby objects to R objects
144 145 146 147 |
# File 'lib/rri/engine.rb', line 144 def add_r_converter(converter) @r_converters ||= [] @r_converters << converter end |
#add_ruby_converter(converter) ⇒ Array
Add a custom converter used to convert R objects to ruby objects
169 170 171 172 |
# File 'lib/rri/engine.rb', line 169 def add_ruby_converter(converter) @ruby_converters ||= [] @ruby_converters << converter end |
#clear_r_converters ⇒ Object
Clear all instance level custom R converters
161 162 163 |
# File 'lib/rri/engine.rb', line 161 def clear_r_converters @r_converters = [] end |
#clear_ruby_converters ⇒ Object
Clear all instance level custom R converters
175 176 177 |
# File 'lib/rri/engine.rb', line 175 def clear_ruby_converters @ruby_converters = [] end |
#convert_and_assign(obj, symbol) ⇒ nil
Convert a ruby value to an R type and assign it to an R variable.
227 228 229 230 231 |
# File 'lib/rri/engine.rb', line 227 def convert_and_assign(obj, symbol) success, rexp = convert_to_r_object(obj) raise RriException.new("Failed to convert ruby object to R object for: #{obj}") unless success simple_assign(symbol, rexp) end |
#convert_to_r_object(obj) ⇒ Array
Convert a ruby object to a R object
Applies converters in 3 levels:
- custom converters that is set for only this engine instance
- custom converters that are set for all engine instances
- default converters
Converters are applied in the reverse order they were added in.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/rri/engine.rb', line 269 def convert_to_r_object(obj) # first try converters defined for just this instance success, value = apply_local_r_converters(obj) return [success, value] if success # then try converters defined in general success, value = apply_r_converters(obj) return [success, value] if success # and finally apply the default converters success, value = apply_default_r_converters(obj) return [success, value] if success # give up [false, obj] end |
#convert_to_ruby_object(rexp) ⇒ Array
Convert an R object to a ruby object
Applies converters in 3 levels:
- custom converters that is set for only this engine instance
- custom converters that are set for all engine instances
- default converters
Converters are applied in the reverse order they were added in.
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/rri/engine.rb', line 299 def convert_to_ruby_object(rexp) # first try converters defined for just this instance success, value = apply_local_ruby_converters(rexp) return [success, value] if success # then try converters defined in general success, value = apply_ruby_converters(rexp) return [success, value] if success # and finally apply the default converters success, value = apply_default_ruby_converters(rexp) return [success, value] if success # give up [false, rexp] end |
#eval_and_convert(expression) ⇒ Object
Eval expression and convert result to the corresponding ruby type
206 207 208 209 210 |
# File 'lib/rri/engine.rb', line 206 def eval_and_convert(expression) success, value = convert_to_ruby_object(@engine.parseAndEval(expression)) raise RriException.new("Failed to convert R object to ruby object for: #{value}") unless success value end |
#get_and_convert(symbol) ⇒ Object
Get a variable from R and convert it to a ruby object
Always uses the global environment.
249 250 251 252 253 254 |
# File 'lib/rri/engine.rb', line 249 def get_and_convert(symbol) rexp = @engine.get(symbol.to_s, nil, true) success, value = convert_to_ruby_object(rexp) raise RriException.new("Failed to convert R object to ruby object for: #{value}") unless success value end |
#r_converters ⇒ Array
Get all instance level custom converters to convert ruby objects to R objects
Converters are returned in the reversed order to how they were added (i.e. the last added is applied first)
155 156 157 158 |
# File 'lib/rri/engine.rb', line 155 def r_converters @r_converters ||= [] @r_converters.reverse end |
#ruby_converters ⇒ Array
Get all instance level custom converters to convert R objects to ruby objects
Converters are returned in the reversed order to how they were added (i.e. the last added is applied first)
185 186 187 188 |
# File 'lib/rri/engine.rb', line 185 def ruby_converters @ruby_converters ||= [] @ruby_converters.reverse end |
#simple_assign(symbol, rexp) ⇒ nil
Helper method to assign expressions to R variables
Always uses the global environment.
218 219 220 |
# File 'lib/rri/engine.rb', line 218 def simple_assign(symbol, rexp) @engine.assign(symbol.to_s, rexp, nil) end |
#simple_eval(expression) ⇒ REXPReference
Helper method to evaluate expressions but avoid any R-to-ruby conversions
Always uses the global environment and returns an R reference which the user can pass along to other R functions later on.
197 198 199 200 |
# File 'lib/rri/engine.rb', line 197 def simple_eval(expression) parsed_expression = @engine.parse(expression, false) @engine.eval(parsed_expression, nil, false) end |
#simple_get(symbol) ⇒ REXPReference
Helper method to get a variable from R
Always uses the global environment.
239 240 241 |
# File 'lib/rri/engine.rb', line 239 def simple_get(symbol) @engine.get(symbol.to_s, nil, false) end |