module R::Support

Public Class Methods

capture() click to toggle source
# File lib/R_interface/r_methods.rb, line 31
    def self.capture
      Polyglot.eval("R", <<-R)
        function(obj, ...) {
          sink(tt <- textConnection("results","w"), split=FALSE, type = c("output", "message"));
          print(obj, ...);
          sink();
          close(tt);
          results
        }
      R
    end
capture2() click to toggle source
# File lib/R_interface/r_methods.rb, line 43
    def self.capture2
      Polyglot.eval("R", <<-R)
        function(obj, ...) {
          tryCatch({
            sink(tt <- textConnection("results","w"), split=FALSE, type = c("output", "message"));
            print(obj, ...);
            sink();
            results
          }, finally = {
            close(tt);
          })
        }
      R
    end
convert_symbol2r(symbol) click to toggle source
# File lib/R_interface/rsupport.rb, line 199
def self.convert_symbol2r(symbol)
  name = symbol.to_s
  # convert '__' to '.'
  name.gsub!(/__/,".")
  # Method 'rclass' is a substitute for R method 'class'.  Needed, as 'class' is also
  # a Ruby method on an object
  name.gsub!("rclass", "class")
  name
end
create_bin_expr(operator) click to toggle source
# File lib/R_interface/r_methods.rb, line 151
    def self.create_bin_expr(operator)
      is_formula = (operator == "`~`")? 'TRUE' : 'FALSE'
      Polyglot.eval("R", <<-R)
        function(op1, op2) {
          o1 = enexpr(op1)
          o2 = enexpr(op2)
          if (typeof(o1) == 'symbol' && o1 == expr(`__`)) {
            o1 = expr(.)
          }
          if (typeof(o2) == 'symbol' && o2 == expr(`__`)) {
            o2 = expr(.)
          }
          exp = expr(#{operator}(!!o1, !!o2))
          if (#{is_formula}) {
            as.formula(exp)
          } else {
            exp
          }
        }
        R
    end
dbk_index() click to toggle source
# File lib/R_interface/r_methods.rb, line 80
    def self.dbk_index
      Polyglot.eval("R", <<-R)
        function(obj, ...) {
          obj[[...]]
        }
      R
    end
enquo() click to toggle source
# File lib/R_interface/r_methods.rb, line 121
    def self.enquo
      Polyglot.eval("R", <<-R)
        function(x, ...) {
          enquo(x)          
        } 
      R
    end
eval(string) click to toggle source
# File lib/R_interface/rsupport.rb, line 85
def self.eval(string)
  begin
    Polyglot.eval("R", string)
  rescue RuntimeError
    raise NoMethodError.new("Method #{string} not found in R environment")
  end
end
exec_function(function, *args) click to toggle source
# File lib/R_interface/rsupport.rb, line 214
def self.exec_function(function, *args)

  begin
    
    # If the execution counter is 0, function was not recursively called
    # Starts capturing output
    if (@@exec_counter == 0)
      R::Support.eval("unlockBinding('r_capture', globalenv())")
      @@con = R::Support.start_capture.call("r_capture")
    end
    
    @@exec_counter = @@exec_counter + 1
    
    # function has no arguments, call it directly
    if (args.length == 0)
      res = R::Object.build(function.call)
    else
      pl = R::Support.parse2list(*args)
      res = @@exec_from_ruby.call(R::Object.method(:build), function, pl)
      # R::Object.build(R::Support.eval("do.call").call(function, pl))
    end

    @@exec_counter = @@exec_counter - 1
    
    # When execution counter back to 0, print the captured output if the length
    # of the output is greater than 0
    if (@@exec_counter == 0)
      R::Support.stop_capture.call(@@con)
      if (R::Support.eval("length(r_capture) > 0")[0])
        cap = R::Object.build(R::Support.eval("r_capture"))
        (0...cap.size).each do |i|
          puts cap >> i
        end
      end
    end

  rescue StandardError => e
    R::Support.stop_capture.call(@@con) if (@@exec_counter == 0)
    raise e
  end

  res
  
end
exec_function_i(function, *args) click to toggle source
# File lib/R_interface/rsupport.rb, line 275
def self.exec_function_i(function, *args)
  pl = R::Support.parse2list(*args)
  R::Support.eval("invoke").call(function, pl)
end
exec_function_name(function_name, *args) click to toggle source
# File lib/R_interface/rsupport.rb, line 264
def self.exec_function_name(function_name, *args)
  # @TODO: should check all that can go wrong when calling eval(function_name) to
  # raise the proper exception
  f = R::Support.eval(function_name)
  R::Support.exec_function(f, *args)
end
interop(object) click to toggle source
# File lib/R_interface/rsupport.rb, line 98
def self.interop(object)
  Truffle::Interop.foreign?(object)
end
md_index() click to toggle source
# File lib/R_interface/r_methods.rb, line 92
    def self.md_index
      Polyglot.eval("R", <<-R)
        function(mdobject, ...) { 
          mdobject[...];
        }
      R
    end
new_scope(symbol, *args, &block) click to toggle source
# File lib/R_interface/rsupport_scope.rb, line 67
def self.new_scope(symbol, *args, &block)
  executionScope = Scope.with(symbol, *args)
  scope = executionScope.new
  scope.instance_eval(&block)
  # scope
end
parse2list(*args) click to toggle source
# File lib/R_interface/rsupport.rb, line 170
def self.parse2list(*args)
  
  params = Polyglot.eval("R", "list()")
  
  args.each_with_index do |arg, i|
    if (arg.is_a? Hash)
      params = parse_hash(arg, params)
    elsif (arg.is_a? NotAvailable)
      params = R::Support.eval("c").call(params, arg.r_interop)
    elsif (arg.is_a? NilClass)
      params = R::Support.eval("`length<-`").call(params, i+1)
    else
      params = R::Support.eval("`[[<-`").
                 call(params, i+1, R::Support.parse_arg(arg))
    end
  end
  
  # if the parameter is an empty list, then add the element NULL to the list
  (Polyglot.eval("R", "length").call(params) == 0) ?
    Polyglot.eval("R", "list").call(nil) : params
  
end
parse_arg(arg) click to toggle source
# File lib/R_interface/rsupport.rb, line 108
def self.parse_arg(arg)

  case(arg)
  when -> (arg) { interop(arg) }
    arg
  when R::Object
    arg.r_interop
  when Numeric
    R::Support.eval('c').call(arg)
  when NegRange
    final_value = (arg.exclude_end?)? (arg.last - 1) : arg.last
    R::Support.eval('seq').call(arg.first, final_value)
  when Range
    final_value = (arg.exclude_end?)? (arg.last - 1) : arg.last
    R::Support.eval('seq').call(arg.first, final_value)
  when :all
    R.empty_symbol
  when Symbol
    arg = R::Support.eval('as.name').call(arg.to_s.gsub(/__/,"."))
  when Proc, Method
    R::RubyCallback.build(arg)
  # This is a Ruby argument that will be automatically converted
  # by the low level Polyglot interface to R
  else 
    arg
  end

end
parse_hash(hsh, lst) click to toggle source
# File lib/R_interface/rsupport.rb, line 141
def self.parse_hash(hsh, lst)

  hsh.each_pair do |key, value|
    k = key.to_s.gsub(/__/,".")
    
    case 
    when (value.is_a? NotAvailable)
      na_named = R::Support.eval("`names<-`").call(value.r_interop, k)
      lst = R::Support.eval("c").call(lst, na_named)
    when (k == 'all')
      lst = R::Support.eval("`[[<-`").
              call(lst, R::Support.eval('`+`').
                          call(R::Support.eval('length').call(lst), 1),
                   R::Support.parse_arg(value))
    else
      lst = R::Support.eval("`[[<-`").
              call(lst, k, R::Support.parse_arg(value))
    end
  end
  
  lst
  
end
pf(interop)
Alias for: print_foreign
print_foreign(interop) click to toggle source
Also aliased as: pf
print_str(obj) click to toggle source
process_missing(symbol, internal, *args) click to toggle source
# File lib/R_interface/rsupport.rb, line 313
def self.process_missing(symbol, internal, *args)

  name = R::Support.convert_symbol2r(symbol)
  
  case name
  # when missing method has an '=' sign in it...
  when ->(x) { x =~ /(.*)=$/ }
    R::Support.set_symbol($1, *args)
  # when missing method is 'eval'... needs special treatment
  when "eval"
    R::Support.r_evaluate(*args)
  else
    function = R::Support.eval(name)
    internal ? R::Support.exec_function_i(function, *args) :
      R::Support.exec_function(function, *args)
  end

end
r_evaluate(*args) click to toggle source
# File lib/R_interface/rsupport.rb, line 299
def self.r_evaluate(*args)
  r_args = args.map { |arg| R::Support.parse_arg(arg) }
  R::Object.build(R::Support.eval("eval").call(*r_args))
end
range() click to toggle source
# File lib/R_interface/r_methods.rb, line 133
    def self.range
      Polyglot.eval("R", <<-R)
        function(x, y, neg = FALSE) {
          e1 = enexpr(x)
          e2 = enexpr(y)
          if (neg) {
            expr(-(!!e1:!!e2))
          } else {
            expr(!!e1:!!e2)
          }
        }
      R
    end
ruby_callback_method() click to toggle source
# File lib/R_interface/r_methods.rb, line 107
    def self.ruby_callback_method
      Polyglot.eval("R", <<-R)
        function(rb_method) {
          function(...) {
          rb_method(...)
          }
        }
      R
    end
set_symbol(name, *args) click to toggle source
# File lib/R_interface/rsupport.rb, line 286
def self.set_symbol(name, *args)
  args << R::Support.eval("globalenv").call()
  R::Support.exec_function_name("assign", name, *args)
end
start_capture() click to toggle source
# File lib/R_interface/r_methods.rb, line 58
    def self.start_capture
      Polyglot.eval("R", <<-R)
        function(cap_variable) {
          sink(con <- textConnection(cap_variable,"w"), split=FALSE, type = c("output"));
          con
        }
      R
    end
stop_capture() click to toggle source
# File lib/R_interface/r_methods.rb, line 67
    def self.stop_capture
      Polyglot.eval("R", <<-R)
        function(con) {
          sink();
          close(con);
        }
      R
    end