Class: R::Object
- Inherits:
-
Object
- Object
- R::Object
- Defined in:
- lib/R_interface/robject.rb
Overview
Direct Known Subclasses
Closure, DataFrame, Environment, Language, List, Matrix, NotAvailable, RExpression, RSymbol, Vector
Instance Attribute Summary collapse
-
#r_interop ⇒ Object
readonly
Returns the value of attribute r_interop.
-
#statement ⇒ Object
Returns the value of attribute statement.
Class Method Summary collapse
-
.build(r_interop) ⇒ Object
————————————————————————————– ————————————————————————————–.
Instance Method Summary collapse
-
#==(other_object) ⇒ Object
————————————————————————————– Checks for equality between two R::Objects.
-
#_(*args) ⇒ Object
—————————————————————————————- We use the following notation to access binary R functions such as %in%: R.vec_ “in”, list.
-
#attr=(which: w, value: v) ⇒ Object
————————————————————————————–.
- #comment ⇒ Object
-
#comment=(comment_text) ⇒ Object
————————————————————————————–.
- #dim ⇒ Object
-
#dim=(numeric_vector) ⇒ Object
————————————————————————————–.
- #dimnames ⇒ Object
-
#dimnames=(names_vector) ⇒ Object
————————————————————————————–.
-
#eql(other_object) ⇒ Object
————————————————————————————– Use eql to check for equality between two objects and receive in return an R::Vector ————————————————————————————–.
-
#initialize(r_interop) ⇒ Object
constructor
————————————————————————————–.
-
#method_missing(symbol, *args, &block) ⇒ Object
————————————————————————————–.
- #names(*args) ⇒ Object
-
#names=(names_vector) ⇒ Object
————————————————————————————– Sets the names attribute of the object ————————————————————————————–.
-
#pp ⇒ Object
————————————————————————————–.
-
#pretty_print(obj) ⇒ Object
————————————————————————————–.
- #rclass ⇒ Object
-
#rclass=(class_name) ⇒ Object
————————————————————————————–.
- #row__names ⇒ Object
-
#row__names=(names_vector) ⇒ Object
since we need to call a method and the method changes the object, then we need to change our internal pointer also @r_interop.
-
#setR(method, *args) ⇒ Object
————————————————————————————– Sets the current object self interop pointer to the returned value of the execution of the given method with arguments.
-
#setR_name(method_name, *args) ⇒ Object
————————————————————————————–.
-
#to_s ⇒ Object
————————————————————————————–.
- #tsp ⇒ Object
-
#tsp=(numeric_vector) ⇒ Object
————————————————————————————–.
Constructor Details
#initialize(r_interop) ⇒ Object
41 42 43 |
# File 'lib/R_interface/robject.rb', line 41 def initialize(r_interop) @r_interop = r_interop end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol, *args, &block) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/R_interface/robject.rb', line 131 def method_missing(symbol, *args, &block) name = R::Support.convert_symbol2r(symbol) # Need to raise a NoMethodError when method_missing is called by an implicit # call to "to_ary". The explanation for that is: # Okay, I've found the source of the behaviour. IOOperations.puts will attempt to # coerce an argument to an array and print its contents, and R::Vector responds to # to_ary but returns the empty array which results in no output. # # Previously IOOperations.puts only checked the type of the argument, and did not # attempt coercion, but that meant we didn't match MRI's behaviour and had some test # failures in other gems. I'd suggest either removing the to_ary methods on # R::Object and R::Vector or implementing them more fully. I see from the comments on # those methods that you needed them for RSpec, it might worth seeing if those problems # still occur and we can look a better way to resolve those. raise NoMethodError if name == "to_ary" case when block_given? R::Support.new_scope(symbol, self, *args, &block) when name =~ /(.*)=$/ method_missing_assign($1, args[0]) when name == "eval" # R function 'eval' needs to be called in a special way, since it expects # the second argument to be an environment. If the arguments are packed # into a list, then there is no second argument and the function fails to # use the second argument as environment R::Support.r_evaluate(@r_interop, *args) when args.length == 0 # no arguments: 2 options: either a named item of the object or apply the function # to the object # if name is a named item of the object, then return the named item named = R::Support.eval("`%in%`"). call(name, R::Support.eval("names").call(@r_interop)) (false === named || !(true === named || named[0])) ? R::Support.exec_function_name(name, @r_interop) : R::Support.exec_function_name("`[[`", @r_interop, name) else args.unshift(@r_interop) R::Support.exec_function_name(name, *args) end end |
Instance Attribute Details
#r_interop ⇒ Object (readonly)
Returns the value of attribute r_interop.
34 35 36 |
# File 'lib/R_interface/robject.rb', line 34 def r_interop @r_interop end |
#statement ⇒ Object
Returns the value of attribute statement.
35 36 37 |
# File 'lib/R_interface/robject.rb', line 35 def statement @statement end |
Class Method Details
.build(r_interop) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/R_interface/robject.rb', line 74 def self.build(r_interop) # if the value is actually not an r_interop, then just return it: native Ruby # object if (!Truffle::Interop.foreign?(r_interop)) # puts "I'm native" return r_interop # a matrix is also a vector... test should come before elsif (R::Support.eval("is.matrix").call(r_interop) == true) # puts "1" R::Matrix.new(r_interop) elsif (R::Support.eval("is.atomic").call(r_interop) == true) # puts "2" Vector.new(r_interop) elsif (R::Support.eval("is.function").call(r_interop) == true) # puts "3" Closure.new(r_interop) elsif (R::Support.eval("is.data.frame").call(r_interop) == true) # puts "4" DataFrame.new(r_interop) elsif (R::Support.eval("is.list").call(r_interop) == true) # puts "5" List.new(r_interop) elsif (R::Support.eval("typeof").call(r_interop) == "language") # @TODO: tests are passing both when we use Language.new # and RExpression.new. Check what should be and write # discriminating tests. # print "robject buid: language\n" # R::Support.print_foreign(r_interop) # puts "6" Language.new(r_interop) # RExpression.new(r_interop) elsif (R::Support.eval("typeof").call(r_interop) == "expression") # puts "7" RExpression.new(r_interop) elsif (R::Support.eval("typeof").call(r_interop) == "name") # puts "8" p "i'm of type name" Name.new(r_interop) elsif (R::Support.eval("typeof").call(r_interop) == "symbol") # puts "9" RSymbol.new(r_interop) elsif (R::Support.eval("typeof").call(r_interop) == "environment") # puts "10" Environment.new(r_interop) else # Generic type # puts "11" p "Generic type: #{R::Support.eval("typeof").call(r_interop).to_s}" r_interop end end |
Instance Method Details
#==(other_object) ⇒ Object
Checks for equality between two R::Objects. This method is used by rspec’s expectation. It returns a Ruby true or false and not an R::Vector with [TRUE] or
- FALSE
51 52 53 54 55 56 57 |
# File 'lib/R_interface/robject.rb', line 51 def ==(other_object) res = R::Support.exec_function_name('identical', @r_interop, R::Support.parse_arg(other_object)) return nil if (res.length >> 0) == 0 res >> 0 end |
#_(*args) ⇒ Object
We use the following notation to access binary R functions such as %in%: R.vec_ “in”, list. arguments are the list of arguments for the function.
182 183 184 185 186 |
# File 'lib/R_interface/robject.rb', line 182 def _(*args) name = "`%#{args.shift.to_s}%`" args.unshift(@r_interop) R::Support.exec_function_name(name, *args) end |
#attr=(which: w, value: v) ⇒ Object
305 306 307 308 309 |
# File 'lib/R_interface/robject.rb', line 305 def attr=(which: w, value: v) value = (R::Support.interop(value) ? value.r_interop : value) # setR(@@set_attr, which, value) setR_name("`attr<-`", which, value) end |
#comment ⇒ Object
246 247 248 |
# File 'lib/R_interface/robject.rb', line 246 def comment R::Support.exec_function_name("comment", @r_interop) end |
#comment=(comment_text) ⇒ Object
242 243 244 |
# File 'lib/R_interface/robject.rb', line 242 def comment=(comment_text) setR_name("`comment<-`", comment_text) end |
#dim ⇒ Object
258 259 260 |
# File 'lib/R_interface/robject.rb', line 258 def dim R::Support.exec_function_name("dim", @r_interop) end |
#dim=(numeric_vector) ⇒ Object
254 255 256 |
# File 'lib/R_interface/robject.rb', line 254 def dim=(numeric_vector) setR_name("`dim<-`", numeric_vector) end |
#dimnames ⇒ Object
270 271 272 |
# File 'lib/R_interface/robject.rb', line 270 def dimnames R::Support.exec_function_name("dimnames", @r_interop) end |
#dimnames=(names_vector) ⇒ Object
266 267 268 |
# File 'lib/R_interface/robject.rb', line 266 def dimnames=(names_vector) setR_name("`dimnames<-`", names_vector) end |
#eql(other_object) ⇒ Object
Use eql to check for equality between two objects and receive in return an R::Vector
63 64 65 66 67 |
# File 'lib/R_interface/robject.rb', line 63 def eql(other_object) # exec_bin_oper("`==`", other_object) R::Support.exec_function_name("`==`", @r_interop, R::Support.parse_arg(other_object)) end |
#names(*args) ⇒ Object
220 221 222 223 224 |
# File 'lib/R_interface/robject.rb', line 220 def names(*args) return R::Support.exec_function_name("names", @r_interop) if (args.length == 0) setR_name("`names<-`", *args) self end |
#names=(names_vector) ⇒ Object
Sets the names attribute of the object
216 217 218 |
# File 'lib/R_interface/robject.rb', line 216 def names=(names_vector) setR_name("`names<-`", names_vector) end |
#pp ⇒ Object
315 316 317 |
# File 'lib/R_interface/robject.rb', line 315 def pp R.print(@r_interop) end |
#pretty_print(obj) ⇒ Object
323 324 325 |
# File 'lib/R_interface/robject.rb', line 323 def pretty_print(obj) puts self end |
#rclass ⇒ Object
234 235 236 |
# File 'lib/R_interface/robject.rb', line 234 def rclass R::Support.exec_function_name("class", @r_interop) end |
#rclass=(class_name) ⇒ Object
230 231 232 |
# File 'lib/R_interface/robject.rb', line 230 def rclass=(class_name) setR_name("`class<-`", class_name) end |
#row__names ⇒ Object
285 286 287 |
# File 'lib/R_interface/robject.rb', line 285 def row__names R::Support.exec_function_name("row.names", @r_interop) end |
#row__names=(names_vector) ⇒ Object
since we need to call a method and the method changes the object, then we need to change our internal pointer also @r_interop. Ideally, just setting the row.names should work.
281 282 283 |
# File 'lib/R_interface/robject.rb', line 281 def row__names=(names_vector) setR_name("`row.names<-`", names_vector) end |
#setR(method, *args) ⇒ Object
Sets the current object self interop pointer to the returned value of the execution of the given method with arguments. This method should be called when R will copy the parameter, but in Ruby we want to hide the copying.
196 197 198 199 |
# File 'lib/R_interface/robject.rb', line 196 def setR(method, *args) @r_interop = R::Support.exec_function_i(method, @r_interop, *args) self end |
#setR_name(method_name, *args) ⇒ Object
205 206 207 208 209 |
# File 'lib/R_interface/robject.rb', line 205 def setR_name(method_name, *args) method = R::Support.eval(method_name) setR(method, *args) self end |
#to_s ⇒ Object
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/R_interface/robject.rb', line 331 def to_s begin cap = nil cap = R::Support.capture2.call(r_interop) str = String.new (0...(cap.size - 1)).each do |i| str << cap[i] << "\n" end str << cap[cap.size - 1] if cap.size >= 1 str rescue StandardError => e puts e end end |
#tsp ⇒ Object
297 298 299 |
# File 'lib/R_interface/robject.rb', line 297 def tsp R::Support.exec_function_name("tsp", @r_interop) end |
#tsp=(numeric_vector) ⇒ Object
293 294 295 |
# File 'lib/R_interface/robject.rb', line 293 def tsp=(numeric_vector) setR_name("`tsp<-`", numeric_vector) end |