Class: RSRuby

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/rsruby.rb,
ext/rsruby/rsruby.c

Constant Summary collapse

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeObject

Starts the R interpreter.



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/rsruby.rb', line 167

def initialize()

  #Initialize in C
  c_initialize

  @@default_mode = NO_DEFAULT

  @@class_table = {}
  @@proc_table  = {}

  #Setup R object cache
  @@cache = {}
  @@cache['get'] = self.get_fun('get')

  #Get constants
  @@cache['TRUE']  = self.__getitem__('T')
  @@cache['FALSE'] = self.__getitem__('F')
  @@cache['NA']    = self.eval_R('NA')
  # @@cache['NAN']   = self.eval_R('as.double(NA)')
  @@cache['NaN']   = self.eval_R('NaN')
  
  #help!
  @@cache['helpfun'] = self.with_mode(NO_CONVERSION, self.__getitem__('help'))

  #Catch errors
  self.eval_R("options(error=expression(NULL))")
  #disable errors
  self.options('show.error.messages' => false)

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.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/rsruby.rb', line 201

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

Class Method Details

.convert_args_to_lcall(args) ⇒ Object

Converts an array of arguments into lcall format. If the last element of the array is a Hash then the contents are interpreted as named arguments. lcall format is an Array of two member Arrays. Each two member array corresponds to a name/argument pair.



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/rsruby.rb', line 262

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 method names from Ruby compatible style into R style.



249
250
251
252
253
254
255
256
# File 'lib/rsruby.rb', line 249

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_modeObject

Returns the current default conversion mode as an Integer.



289
290
291
# File 'lib/rsruby.rb', line 289

def RSRuby.get_default_mode
  @@default_mode
end

.get_rsruby_inputObject



297
298
299
# File 'lib/rsruby.rb', line 297

def RSRuby.get_rsruby_input
  @@rsruby_input
end

.get_rsruby_outputObject



304
305
306
# File 'lib/rsruby.rb', line 304

def RSRuby.get_rsruby_output
  @@rsruby_output
end

.get_rsruby_showfilesObject



311
312
313
# File 'lib/rsruby.rb', line 311

def RSRuby.get_rsruby_showfiles
  @@rsruby_showfiles
end

.set_default_mode(m) ⇒ Object

Sets the default conversion mode for RSRuby. The constants defined in #RSRuby should be used



282
283
284
285
286
287
# File 'lib/rsruby.rb', line 282

def RSRuby.set_default_mode(m)
  if m < -1 or m > TOP_CONVERSION
    raise ArgumentError, "Invalid mode requested"
  end
  @@default_mode = m
end

.set_rsruby_input(m) ⇒ Object

TODO - input/output setting methods don’t work atm



294
295
296
# File 'lib/rsruby.rb', line 294

def RSRuby.set_rsruby_input(m)
  @@rsruby_input = m
end

.set_rsruby_output(m) ⇒ Object



301
302
303
# File 'lib/rsruby.rb', line 301

def RSRuby.set_rsruby_output(m)
  @@rsruby_output = m
end

.set_rsruby_showfiles(m) ⇒ Object



308
309
310
# File 'lib/rsruby.rb', line 308

def RSRuby.set_rsruby_showfiles(m)
  @@rsruby_showfiles = m
end

Instance Method Details

#[](r_id) ⇒ Object

As method_missing, but only returns the R function/object does not call it.



228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/rsruby.rb', line 228

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) ⇒ Object



347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/rsruby.rb', line 347

def __getitem__(name)

  #Find the identifier and cache (unless already cached)
  unless @@cache.has_key?(name)
    @@cache[name] = @@cache['get'].lcall([['',name]])
  end

  #Retrieve object from cache
  robj = @@cache[name]

  return robj

end

#c_initializeObject



162
# File 'lib/rsruby.rb', line 162

alias c_initialize initialize

#class_tableObject

Returns the current class table Hash for RSRuby.



316
317
318
# File 'lib/rsruby.rb', line 316

def class_table
  @@class_table
end

#class_table=(h) ⇒ Object

Sets the RSRuby class table Hash.



321
322
323
# File 'lib/rsruby.rb', line 321

def class_table=(h)
  @@class_table = h
end

#eval_R(s) ⇒ Object

Evaluates the given string in R. Returns the result of the evaluation.



336
337
338
# File 'lib/rsruby.rb', line 336

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



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
# File 'ext/rsruby/rsruby.c', line 94

VALUE get_fun(VALUE self, VALUE name){

  VALUE str;
  int conversion=TOP_MODE;
  SEXP robj;
  VALUE  rubyobj;
  VALUE  params[2];
  char* cstr_name;

  str = StringValue(name);

  cstr_name = RSTRING(str)->ptr;

  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));

  return rubyobj;

}

#help(*args) ⇒ Object

Wraps the R help function.



341
342
343
344
# File 'lib/rsruby.rb', line 341

def help(*args)
  helpobj = @@cache['helpfun'].call(args)
  self.print(helpobj)
end

#proc_tableObject

Returns the current proc table Hash for RSRuby.



326
327
328
# File 'lib/rsruby.rb', line 326

def proc_table
  @@proc_table
end

#proc_table=(h) ⇒ Object

Sets the RSRuby proc table Hash.



331
332
333
# File 'lib/rsruby.rb', line 331

def proc_table=(h)
  @@proc_table = h
end

#shutdownObject

TODO - Shutdown is not working correctly



140
141
142
143
144
145
146
147
# File 'ext/rsruby/rsruby.c', line 140

VALUE cShutdown(VALUE self){

  r_finalize();

  self = Qnil;
  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.



243
244
245
246
# File 'lib/rsruby.rb', line 243

def with_mode(mode,func)
  func.wrap = mode
  return func
end