rsruby 0.4.5 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +3 -1
- data/Rakefile.rb +153 -0
- data/ext/Converters.c +33 -34
- data/ext/Converters.h +1 -1
- data/ext/extconf.rb +1 -1
- data/ext/robj.c +41 -6
- data/ext/rsruby.c +27 -15
- data/ext/rsruby.h +10 -5
- data/lib/rsruby.rb +65 -48
- data/lib/rsruby/dataframe.rb +28 -3
- data/test/tc_array.rb +5 -1
- data/test/tc_boolean.rb +6 -0
- data/test/tc_cleanup.rb +10 -8
- data/test/tc_eval.rb +2 -0
- data/test/tc_extensions.rb +18 -2
- data/test/tc_init.rb +11 -0
- data/test/tc_matrix.rb +23 -0
- data/test/tc_to_r.rb +3 -1
- data/test/tc_to_ruby.rb +3 -2
- data/test/test_all.rb +1 -0
- metadata +51 -41
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
History.txt
|
2
2
|
License.txt
|
3
3
|
Manifest.txt
|
4
|
-
README.txt
|
4
|
+
README.txt
|
5
|
+
Rakefile.rb
|
5
6
|
examples/arrayfields.rb
|
6
7
|
examples/bioc.rb
|
7
8
|
examples/dataframe.rb
|
@@ -27,6 +28,7 @@ test/tc_extensions.rb
|
|
27
28
|
test/tc_init.rb
|
28
29
|
test/tc_io.rb
|
29
30
|
test/tc_library.rb
|
31
|
+
test/tc_matrix.rb
|
30
32
|
test/tc_modes.rb
|
31
33
|
test/tc_robj.rb
|
32
34
|
test/tc_sigint.rb
|
data/Rakefile.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift("./lib")
|
4
|
+
$LOAD_PATH.unshift("./ext")
|
5
|
+
|
6
|
+
gem_name = RUBY_PLATFORM !~ /mswin32$/ ? "rsruby" : "rsrubywin"
|
7
|
+
hoe = Hoe.new(gem_name,'0.5') do |p|
|
8
|
+
|
9
|
+
p.author = "Alex Gutteridge"
|
10
|
+
p.email = "ag357@cam.ac.uk"
|
11
|
+
p.url = "http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/"
|
12
|
+
|
13
|
+
p.description = p.paragraphs_of("README.txt",1..3)[0]
|
14
|
+
p.summary = p.paragraphs_of("README.txt",1)[0]
|
15
|
+
p.changes = p.paragraphs_of("History.txt",0..1).join("\n\n")
|
16
|
+
|
17
|
+
p.clean_globs = ["ext/*.o","ext/*.so","ext/Makefile","ext/mkmf.log","**/*~","email.txt","manual.{aux,log,out,toc,pdf}"]
|
18
|
+
|
19
|
+
p.rdoc_pattern = /(^lib\/.*\.rb$|^examples\/.*\.rb$|^README|^History|^License)/
|
20
|
+
|
21
|
+
p.spec_extras = {
|
22
|
+
:extensions => RUBY_PLATFORM !~ /mswin32$/ ? ['ext/extconf.rb'] : [],
|
23
|
+
:require_paths => ['lib','test','ext'],
|
24
|
+
:has_rdoc => true,
|
25
|
+
:extra_rdoc_files => ["README.txt","History.txt","License.txt"] + FileList["examples/*"],
|
26
|
+
:rdoc_options => ["--exclude", "test/*", "--main", "README.txt", "--inline-source"]
|
27
|
+
}
|
28
|
+
|
29
|
+
task :setup_rb_package => [:clean, :package] do
|
30
|
+
|
31
|
+
package_dir = "#{p.name}-#{p.version}"
|
32
|
+
cp("setup.rb","pkg/#{package_dir}")
|
33
|
+
#cp("manual.pdf","pkg/#{package_dir}")
|
34
|
+
|
35
|
+
Dir.chdir("pkg")
|
36
|
+
system("tar -czf #{p.name}-#{p.version}.tgz #{package_dir}")
|
37
|
+
Dir.chdir("..")
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
hoe.spec.dependencies.delete_if{|dep| dep.name == "hoe"}
|
44
|
+
if RUBY_PLATFORM =~ /mswin32$/
|
45
|
+
# add the precompiled rsruby_c.so into the gemspec
|
46
|
+
hoe.spec.files = hoe.spec.files + ["ext/rsruby_c.so"]
|
47
|
+
|
48
|
+
# add the :build_extension task to :gem so that the extension gets
|
49
|
+
# built BEFORE packaging (note the task needs to occur first)
|
50
|
+
Rake.application.lookup(:gem).prerequisites.unshift(:build_extension)
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Uses extconf.rb and make to build the extension"
|
54
|
+
task :build_extension => ['ext/rsruby_c.so']
|
55
|
+
SRC = FileList['ext/*.c'] + FileList['ext/*.h']
|
56
|
+
file 'ext/rsruby_c.so' => SRC do
|
57
|
+
Dir.chdir('ext')
|
58
|
+
if RUBY_PLATFORM !~ /mswin32$/
|
59
|
+
system("ruby extconf.rb -- --with-R-dir=$R_HOME --with-R-include=/usr/share/R/include/")
|
60
|
+
system("make")
|
61
|
+
else
|
62
|
+
# Windows-specific build that does not use extconf.rb or make
|
63
|
+
# This build was designed using the default One-Click Installer
|
64
|
+
# for Windows (1.8.6-25) and MinGW (5.1.3). Both are freely
|
65
|
+
# available. See the following websites for downloads and
|
66
|
+
# installation information:
|
67
|
+
#
|
68
|
+
# http://rubyforge.org/projects/rubyinstaller/
|
69
|
+
# http://www.mingw.org/
|
70
|
+
#
|
71
|
+
|
72
|
+
# TODO -
|
73
|
+
# * add checks for installation paths
|
74
|
+
# * rewrite this build in terms of rake rules? (or at least check
|
75
|
+
# so that up-to-date files are not rebuilt)
|
76
|
+
# * add configuration options a-la extconf.rb
|
77
|
+
|
78
|
+
# Note: here I use slashes '/' rather than backslashes '\' in the paths.
|
79
|
+
# If you enter the gcc command into the command prompt, you do NOT
|
80
|
+
# need to use the *nix-style paths. Here it's necessary so the backslashes
|
81
|
+
# aren't treated as character escapes in the ruby strings.
|
82
|
+
ruby_install_dir = ENV['RUBY_INSTALL_DIR'] || "C:/ruby"
|
83
|
+
ruby_headers_dir = "#{ruby_install_dir}/lib/ruby/1.8/i386-mswin32"
|
84
|
+
ruby_lib_dir = "#{ruby_install_dir}/lib"
|
85
|
+
|
86
|
+
r_install_dir = ENV['R_INSTALL_DIR'] || "C:/Program Files/R/R-2.6.0"
|
87
|
+
r_headers_dir = "#{r_install_dir}/include"
|
88
|
+
r_lib_dir = "#{r_install_dir}/bin"
|
89
|
+
|
90
|
+
# These defines are all added for a clean compile. I'm not sure if
|
91
|
+
# setting these flags is appropriate, but they do work.
|
92
|
+
# HAVE_R_H:: extconf.rb includes this flag
|
93
|
+
# HAVE_ISINF:: prevents "isinf" redefinition
|
94
|
+
# _MSC_VER:: prevents "MSC version unmatch" error -- it may not be smart to bypass this check
|
95
|
+
# STRICT_R_HEADERS:: prevents "ERROR" redefinition
|
96
|
+
defines = "-DHAVE_R_H -DHAVE_ISINF -D_MSC_VER=1200 -DSTRICT_R_HEADERS"
|
97
|
+
|
98
|
+
# check required files exist
|
99
|
+
[ruby_headers_dir, ruby_lib_dir].each do |dir|
|
100
|
+
next if File.exists?(dir)
|
101
|
+
raise %Q{
|
102
|
+
Build Error:
|
103
|
+
ruby directory does not exist (#{dir})
|
104
|
+
Try setting RUBY_INSTALL_DIR to the ruby installation directory.
|
105
|
+
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
[r_headers_dir, r_lib_dir].each do |dir|
|
110
|
+
next if File.exists?(dir)
|
111
|
+
raise %Q{
|
112
|
+
Build Error:
|
113
|
+
R directory does not exist (#{dir})
|
114
|
+
Try setting R_INSTALL_DIR to the R installation directory.
|
115
|
+
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
OBJ = SRC.collect do |src|
|
120
|
+
next unless File.extname(src) == ".c"
|
121
|
+
|
122
|
+
# at this point the src files are like 'ext/src.c'
|
123
|
+
src = File.basename(src)
|
124
|
+
|
125
|
+
# compile each source file, using the same flags as extconf.rb
|
126
|
+
# notice the quotes encapsulating the include paths, so that
|
127
|
+
# spaces are allowed (as in the R default install path)
|
128
|
+
sh( %Q{gcc -I. -I"#{ruby_headers_dir}" -I"#{r_headers_dir}" #{defines} -g -O2 -c #{src}} )
|
129
|
+
|
130
|
+
# double duty... collect the .o filenames
|
131
|
+
File.basename(src).chomp(".c") + ".o"
|
132
|
+
end.compact
|
133
|
+
|
134
|
+
# same notes as extconf.rb
|
135
|
+
sh( %Q{gcc -shared -s -L. -Wl,--enable-auto-image-base,--enable-auto-import,--export-all -L"#{ruby_lib_dir}" -L"#{r_lib_dir}" -o rsruby_c.so #{OBJ.join(" ")} -lmsvcrt-ruby18 -lR -lwsock32})
|
136
|
+
end
|
137
|
+
Dir.chdir('..')
|
138
|
+
end
|
139
|
+
|
140
|
+
task :test => [:build_extension]
|
141
|
+
|
142
|
+
desc "Build PDF manual"
|
143
|
+
task :build_manual => ["manual.pdf"]
|
144
|
+
file "manual.pdf" => ["manual.tex"] do
|
145
|
+
out = 'Rerun'
|
146
|
+
while out.match(/Rerun/)
|
147
|
+
out = `pdflatex manual.tex`
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
task :build_manual_clean => [:build_manual] do
|
152
|
+
system("rm manual.{aux,log,out,toc}")
|
153
|
+
end
|
data/ext/Converters.c
CHANGED
@@ -38,6 +38,8 @@
|
|
38
38
|
SEXP ruby_to_R(VALUE obj)
|
39
39
|
{
|
40
40
|
SEXP robj;
|
41
|
+
VALUE str;
|
42
|
+
char buf [100];
|
41
43
|
|
42
44
|
//Return nil if object is nil
|
43
45
|
if (obj == Qnil) {
|
@@ -99,7 +101,10 @@ SEXP ruby_to_R(VALUE obj)
|
|
99
101
|
}
|
100
102
|
else
|
101
103
|
{
|
102
|
-
|
104
|
+
str = rb_funcall(obj,rb_intern("inspect"),0);
|
105
|
+
str = rb_funcall(str,rb_intern("slice"),2,INT2NUM(0),INT2NUM(60));
|
106
|
+
sprintf(buf,"Unsupported object '%s' passed to R.\n",RSTRING(str)->ptr);
|
107
|
+
rb_raise(rb_eArgError,buf);
|
103
108
|
PROTECT(robj = NULL); /* Protected to avoid stack inbalance */
|
104
109
|
}
|
105
110
|
|
@@ -143,8 +148,8 @@ SEXP array_to_R(VALUE obj)
|
|
143
148
|
|
144
149
|
state = -1;
|
145
150
|
for (i=0; i<RARRAY(obj)->len; i++) {
|
146
|
-
|
147
|
-
|
151
|
+
|
152
|
+
it = rb_ary_entry(obj, i);
|
148
153
|
|
149
154
|
if (state < 0)
|
150
155
|
state = type_to_int(it);
|
@@ -183,6 +188,7 @@ SEXP array_to_R(VALUE obj)
|
|
183
188
|
|
184
189
|
exception:
|
185
190
|
UNPROTECT(1);
|
191
|
+
rb_raise(rb_eArgError,"Error converting Array to R\n");
|
186
192
|
return NULL;
|
187
193
|
}
|
188
194
|
|
@@ -193,6 +199,12 @@ hash_to_R(VALUE obj)
|
|
193
199
|
VALUE keys, values;
|
194
200
|
SEXP robj, names;
|
195
201
|
|
202
|
+
//TODO - Baffling. Not sure what's wrong with these functions?
|
203
|
+
//rb_hash_keys(proc_table);
|
204
|
+
//rb_hash_values(proc_table);
|
205
|
+
//rb_hash_size(proc_table);
|
206
|
+
//compiles, but complains they are undefined symbols when run...
|
207
|
+
|
196
208
|
if (FIX2INT(rb_funcall(obj,rb_intern("size"),0)) == 0)
|
197
209
|
return R_NilValue;
|
198
210
|
|
@@ -421,12 +433,15 @@ from_proc_table(SEXP robj, VALUE *fun)
|
|
421
433
|
VALUE args[2];
|
422
434
|
int i, l, error;
|
423
435
|
|
424
|
-
proc_table =
|
425
|
-
rb_intern("RSRuby")),
|
426
|
-
rb_intern("@@proc_table"));
|
436
|
+
proc_table = rb_iv_get(RSRUBY,"@proc_table");
|
427
437
|
|
428
438
|
proc = Qnil;
|
429
439
|
|
440
|
+
//TODO - Baffling. Not sure what's wrong with these functions?
|
441
|
+
//procs = rb_hash_keys(proc_table);
|
442
|
+
//funs = rb_hash_values(proc_table);
|
443
|
+
//l = FIX2INT(rb_hash_size(proc_table));
|
444
|
+
|
430
445
|
procs = rb_funcall(proc_table,rb_intern("keys"),0);
|
431
446
|
funs = rb_funcall(proc_table,rb_intern("values"),0);
|
432
447
|
l = FIX2INT(rb_funcall(proc_table,rb_intern("size"),0));
|
@@ -440,13 +455,10 @@ from_proc_table(SEXP robj, VALUE *fun)
|
|
440
455
|
for (i=0; i<l; i++) {
|
441
456
|
proc = rb_ary_entry(procs, i);
|
442
457
|
|
443
|
-
mode =
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
rb_intern("RSRuby")),
|
448
|
-
rb_intern("@@default_mode"),
|
449
|
-
INT2FIX(BASIC_CONVERSION),Qtrue);
|
458
|
+
mode = rb_iv_get(RSRUBY,"@default_mode");
|
459
|
+
rb_iv_set(RSRUBY,
|
460
|
+
"@default_mode",
|
461
|
+
INT2FIX(BASIC_CONVERSION));
|
450
462
|
|
451
463
|
//New safe code
|
452
464
|
args[0] = proc;
|
@@ -469,10 +481,9 @@ VALUE call_proc(VALUE data){
|
|
469
481
|
|
470
482
|
VALUE reset_mode(VALUE mode){
|
471
483
|
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
mode,Qtrue);
|
484
|
+
rb_iv_set(RSRUBY,
|
485
|
+
"@default_mode",
|
486
|
+
mode);
|
476
487
|
|
477
488
|
return Qnil;
|
478
489
|
|
@@ -504,13 +515,8 @@ to_ruby_proc(SEXP robj, VALUE *obj)
|
|
504
515
|
rb_iv_set(tmp,"@wrap",Qfalse);
|
505
516
|
|
506
517
|
//Again set conversion mode to basic to prevent recursion
|
507
|
-
mode =
|
508
|
-
|
509
|
-
rb_intern("@@default_mode"));
|
510
|
-
rb_cvar_set(rb_const_get(rb_cObject,
|
511
|
-
rb_intern("RSRuby")),
|
512
|
-
rb_intern("@@default_mode"),
|
513
|
-
INT2FIX(BASIC_CONVERSION),Qtrue);
|
518
|
+
mode = rb_iv_get(RSRUBY,"@default_mode");
|
519
|
+
rb_iv_set(RSRUBY, "@default_mode", INT2FIX(BASIC_CONVERSION));
|
514
520
|
|
515
521
|
//New safe code
|
516
522
|
args[0] = fun;
|
@@ -527,9 +533,7 @@ VALUE from_class_table(SEXP robj)
|
|
527
533
|
VALUE key, fun, class_table;
|
528
534
|
int i;
|
529
535
|
|
530
|
-
class_table =
|
531
|
-
rb_intern("RSRuby")),
|
532
|
-
rb_intern("@@class_table"));
|
536
|
+
class_table = rb_iv_get(RSRUBY, "@class_table");
|
533
537
|
|
534
538
|
PROTECT(rclass = GET_CLASS(robj));
|
535
539
|
|
@@ -577,13 +581,8 @@ to_ruby_class(SEXP robj, VALUE *obj)
|
|
577
581
|
rb_iv_set(tmp,"@wrap",Qfalse);
|
578
582
|
|
579
583
|
//Again set conversion mode to basic to prevent recursion
|
580
|
-
mode =
|
581
|
-
|
582
|
-
rb_intern("@@default_mode"));
|
583
|
-
rb_cvar_set(rb_const_get(rb_cObject,
|
584
|
-
rb_intern("RSRuby")),
|
585
|
-
rb_intern("@@default_mode"),
|
586
|
-
INT2FIX(BASIC_CONVERSION),Qtrue);
|
584
|
+
mode = rb_iv_get(RSRUBY, "@default_mode");
|
585
|
+
rb_iv_set(RSRUBY, "@default_mode", INT2FIX(BASIC_CONVERSION));
|
587
586
|
|
588
587
|
//New safe code
|
589
588
|
args[0] = fun;
|
data/ext/Converters.h
CHANGED
@@ -58,7 +58,7 @@ VALUE to_ruby_hash(VALUE obj, SEXP names);
|
|
58
58
|
VALUE to_ruby_array(VALUE obj, int *dims, int l);
|
59
59
|
|
60
60
|
VALUE ltranspose(VALUE list, int *dims, int *strides,
|
61
|
-
|
61
|
+
int pos, int shift, int len);
|
62
62
|
|
63
63
|
//Macros for quick checks
|
64
64
|
#define Robj_Check(v) (rb_obj_is_instance_of(v,rb_const_get(rb_cObject,rb_intern("RObj"))))
|
data/ext/extconf.rb
CHANGED
data/ext/robj.c
CHANGED
@@ -70,9 +70,7 @@ VALUE RObj_lcall(VALUE self, VALUE args){
|
|
70
70
|
return Qnil;
|
71
71
|
}
|
72
72
|
|
73
|
-
default_mode = NUM2INT(
|
74
|
-
rb_intern("RSRuby")),
|
75
|
-
rb_intern("@@default_mode")));
|
73
|
+
default_mode = NUM2INT(rb_iv_get(RSRUBY,"@default_mode"));
|
76
74
|
|
77
75
|
// Convert
|
78
76
|
if (default_mode < 0){
|
@@ -88,6 +86,45 @@ VALUE RObj_lcall(VALUE self, VALUE args){
|
|
88
86
|
return obj;
|
89
87
|
}
|
90
88
|
|
89
|
+
|
90
|
+
//lcall method that is safe to call during RSRuby initialisation
|
91
|
+
VALUE RObj_init_lcall(VALUE self, VALUE args){
|
92
|
+
SEXP exp, e, res;
|
93
|
+
SEXP r_obj;
|
94
|
+
VALUE obj;
|
95
|
+
|
96
|
+
//Ensure we have an array
|
97
|
+
args = rb_check_array_type(args);
|
98
|
+
|
99
|
+
// A SEXP with the function to call and the arguments
|
100
|
+
PROTECT(exp = allocVector(LANGSXP, (RARRAY(args)->len)+1));
|
101
|
+
e = exp;
|
102
|
+
|
103
|
+
Data_Get_Struct(self, struct SEXPREC, r_obj);
|
104
|
+
|
105
|
+
SETCAR(e, r_obj);
|
106
|
+
e = CDR(e);
|
107
|
+
|
108
|
+
// Add the arguments to the SEXP
|
109
|
+
if (!make_argl(args, &e)) {
|
110
|
+
UNPROTECT(1);
|
111
|
+
return Qnil;
|
112
|
+
}
|
113
|
+
|
114
|
+
// Evaluate
|
115
|
+
PROTECT(res = do_eval_expr(exp));
|
116
|
+
if (!res) {
|
117
|
+
UNPROTECT(2);
|
118
|
+
return Qnil;
|
119
|
+
}
|
120
|
+
|
121
|
+
obj = to_ruby_with_mode(res, BASIC_CONVERSION);
|
122
|
+
|
123
|
+
UNPROTECT(2);
|
124
|
+
|
125
|
+
return obj;
|
126
|
+
}
|
127
|
+
|
91
128
|
/* Convert a sequence of (name, value) pairs to arguments to an R
|
92
129
|
function call */
|
93
130
|
int
|
@@ -145,9 +182,7 @@ VALUE RObj_to_ruby(VALUE self, VALUE args){
|
|
145
182
|
}
|
146
183
|
|
147
184
|
if (RARRAY(args)->len == 0){
|
148
|
-
conv = NUM2INT(
|
149
|
-
rb_intern("RSRuby")),
|
150
|
-
rb_intern("@@default_mode")));
|
185
|
+
conv = NUM2INT(rb_iv_get(RSRUBY,"@default_mode"));
|
151
186
|
} else {
|
152
187
|
conv = NUM2INT(rb_ary_entry(args,0));
|
153
188
|
}
|
data/ext/rsruby.c
CHANGED
@@ -33,7 +33,7 @@
|
|
33
33
|
|
34
34
|
/* Global list to protect R objects from garbage collection */
|
35
35
|
/* This is inspired in $R_SRC/src/main/memory.c */
|
36
|
-
static SEXP R_References;
|
36
|
+
//static SEXP R_References;
|
37
37
|
|
38
38
|
SEXP
|
39
39
|
RecursiveRelease(SEXP obj, SEXP list)
|
@@ -48,19 +48,18 @@ RecursiveRelease(SEXP obj, SEXP list)
|
|
48
48
|
}
|
49
49
|
|
50
50
|
/* TODO: This needs implementing as a Ruby destructor for each RObj */
|
51
|
-
void
|
52
|
-
Robj_dealloc(VALUE self)
|
53
|
-
{
|
54
|
-
/* Remove the object from the list of protected objects */
|
51
|
+
/*static void
|
52
|
+
Robj_dealloc(VALUE self)
|
53
|
+
{
|
55
54
|
SEXP robj;
|
56
|
-
|
55
|
+
|
57
56
|
Data_Get_Struct(self, struct SEXPREC, robj);
|
58
|
-
|
57
|
+
|
59
58
|
R_References = RecursiveRelease(robj, R_References);
|
60
59
|
SET_SYMVALUE(install("R.References"), R_References);
|
61
|
-
|
60
|
+
|
62
61
|
return;
|
63
|
-
}
|
62
|
+
}*/
|
64
63
|
|
65
64
|
|
66
65
|
/* Obtain an R object via its name.
|
@@ -73,7 +72,6 @@ VALUE get_fun(VALUE self, VALUE name){
|
|
73
72
|
int conversion=TOP_MODE;
|
74
73
|
SEXP robj;
|
75
74
|
VALUE rubyobj;
|
76
|
-
//VALUE params[2];
|
77
75
|
char* cstr_name;
|
78
76
|
|
79
77
|
str = StringValue(name);
|
@@ -104,6 +102,7 @@ void r_finalize(void)
|
|
104
102
|
R_RunExitFinalizers();
|
105
103
|
CleanEd();
|
106
104
|
KillAllDevices();
|
105
|
+
|
107
106
|
if((tmpdir = getenv("R_SESSION_TMPDIR"))) {
|
108
107
|
snprintf((char *)buf, 1024, "rm -rf %s", tmpdir);
|
109
108
|
R_system((char *)buf);
|
@@ -116,9 +115,10 @@ void r_finalize(void)
|
|
116
115
|
/*
|
117
116
|
* Shutdown the R interpreter
|
118
117
|
*/
|
119
|
-
VALUE
|
118
|
+
VALUE rs_shutdown(VALUE self){
|
120
119
|
|
121
120
|
r_finalize();
|
121
|
+
Rf_endEmbeddedR(0);
|
122
122
|
return Qtrue;
|
123
123
|
|
124
124
|
}
|
@@ -147,24 +147,36 @@ void init_R(int argc, char **argv){
|
|
147
147
|
char *defaultArgv[] = {"rsruby","-q","--vanilla"};
|
148
148
|
|
149
149
|
Rf_initEmbeddedR(sizeof(defaultArgv) / sizeof(defaultArgv[0]), defaultArgv);
|
150
|
+
R_Interactive = FALSE; //Remove crash menu (and other interactive R features)
|
150
151
|
}
|
152
|
+
|
153
|
+
/* This method is for testing catching of segfaults */
|
154
|
+
VALUE crash(){
|
155
|
+
int* ptr = (int*)0;
|
156
|
+
*ptr = 1;
|
157
|
+
return Qtrue;
|
158
|
+
}
|
159
|
+
|
151
160
|
|
152
161
|
/* Ruby code */
|
153
162
|
|
154
163
|
VALUE cRRuby;
|
155
164
|
VALUE cRObj;
|
156
165
|
|
157
|
-
void
|
166
|
+
void Init_rsruby_c(){
|
158
167
|
|
159
168
|
cRRuby = rb_define_class("RSRuby",rb_cObject);
|
160
|
-
cRObj = rb_const_get(rb_cObject,rb_intern("RObj"));
|
161
169
|
|
162
|
-
rb_define_method(cRRuby, "
|
170
|
+
rb_define_method(cRRuby, "r_init", rr_init, 0);
|
163
171
|
rb_define_method(cRRuby, "get_fun", get_fun, 1);
|
164
|
-
rb_define_method(cRRuby, "shutdown",
|
172
|
+
rb_define_method(cRRuby, "shutdown", rs_shutdown, 0);
|
173
|
+
|
174
|
+
rb_define_method(cRRuby, "crash", crash, 0);
|
165
175
|
|
166
176
|
//Add the lcall method to RObj
|
177
|
+
cRObj = rb_const_get(rb_cObject,rb_intern("RObj"));
|
167
178
|
rb_define_method(cRObj, "lcall", RObj_lcall, 1);
|
179
|
+
rb_define_method(cRObj, "__init_lcall__", RObj_init_lcall, 1);
|
168
180
|
rb_define_method(cRObj, "to_ruby", RObj_to_ruby, -2);
|
169
181
|
|
170
182
|
}
|
data/ext/rsruby.h
CHANGED
@@ -55,13 +55,16 @@
|
|
55
55
|
|
56
56
|
#define TOP_MODE 4
|
57
57
|
|
58
|
+
#define RSRUBY rb_funcall(rb_const_get(rb_cObject,rb_intern("RSRuby")),rb_intern("instance"),0)
|
59
|
+
|
58
60
|
/* Missing definitions from Rinterface.h or RStartup.h */
|
59
61
|
# define CleanEd Rf_CleanEd
|
62
|
+
extern int Rf_initEmbeddedR(int argc, char **argv);
|
63
|
+
extern int R_Interactive;
|
60
64
|
extern void CleanEd(void);
|
61
65
|
extern int R_CollectWarnings;
|
62
66
|
# define PrintWarnings Rf_PrintWarnings
|
63
67
|
extern void PrintWarnings(void);
|
64
|
-
extern void Rf_initEmbeddedR(int argc, char **argv);
|
65
68
|
|
66
69
|
void Init_rsruby();
|
67
70
|
|
@@ -69,14 +72,16 @@ void init_R(int argc, char *argv[0]);
|
|
69
72
|
void r_finalize(void);
|
70
73
|
|
71
74
|
SEXP RecursiveRelease(SEXP obj, SEXP list);
|
72
|
-
void Robj_dealloc(VALUE self);
|
75
|
+
//static void Robj_dealloc(VALUE self);
|
73
76
|
|
74
|
-
VALUE
|
77
|
+
VALUE rs_shutdown(VALUE self);
|
75
78
|
VALUE get_fun(VALUE self, VALUE name);
|
76
|
-
VALUE rr_init(VALUE self);
|
79
|
+
VALUE rr_init(VALUE self);
|
80
|
+
|
81
|
+
VALUE crash(void);
|
77
82
|
|
78
83
|
VALUE RObj_lcall(VALUE self, VALUE args);
|
84
|
+
VALUE RObj_init_lcall(VALUE self, VALUE args);
|
79
85
|
VALUE RObj_to_ruby(VALUE self, VALUE args);
|
80
86
|
int make_argl(VALUE args, SEXP *e);
|
81
|
-
|
82
87
|
#endif
|
data/lib/rsruby.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rsruby/robj'
|
2
|
-
require '
|
2
|
+
require 'rsruby_c'
|
3
3
|
require 'singleton'
|
4
4
|
|
5
5
|
require 'complex'
|
@@ -53,7 +53,7 @@ require 'complex'
|
|
53
53
|
|
54
54
|
class RSRuby
|
55
55
|
|
56
|
-
VERSION = '0.
|
56
|
+
VERSION = '0.5'
|
57
57
|
|
58
58
|
include Singleton
|
59
59
|
|
@@ -66,40 +66,63 @@ class RSRuby
|
|
66
66
|
NO_CONVERSION = 0
|
67
67
|
NO_DEFAULT = -1
|
68
68
|
|
69
|
-
|
69
|
+
attr_accessor :proc_table, :class_table, :default_mode, :caching
|
70
70
|
|
71
71
|
#Create a new RSRuby interpreter instance. The Singleton design pattern
|
72
72
|
#ensures that only one instance can be running in a script. Further
|
73
73
|
#calls to RSRuby.instance will return the original instance.
|
74
74
|
def initialize()
|
75
75
|
|
76
|
-
#Initialize
|
77
|
-
|
76
|
+
#Initialize R
|
77
|
+
r_init
|
78
78
|
|
79
|
-
|
79
|
+
@default_mode = NO_DEFAULT
|
80
80
|
|
81
|
-
|
82
|
-
|
81
|
+
@class_table = {}
|
82
|
+
@proc_table = {}
|
83
|
+
|
84
|
+
@caching = true
|
85
|
+
reset_cache
|
86
|
+
|
87
|
+
#Catch errors
|
88
|
+
self.__init_eval_R__("options(error=expression(NULL))")
|
89
|
+
#disable errors
|
90
|
+
self.__init_eval_R__("options(show.error.messages=F)")
|
83
91
|
|
92
|
+
end
|
93
|
+
|
94
|
+
def reset_cache
|
84
95
|
#Setup R object cache
|
85
|
-
|
86
|
-
|
96
|
+
@cache = {}
|
97
|
+
@cache['get'] = self.get_fun('get')
|
87
98
|
|
88
99
|
#Get constants
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
100
|
+
@cache['TRUE'] = self.__getitem__('T',true)
|
101
|
+
@cache['FALSE'] = self.__getitem__('F',true)
|
102
|
+
|
103
|
+
@cache['parse'] = self.__getitem__('parse',true)
|
104
|
+
@cache['eval'] = self.__getitem__('eval',true)
|
105
|
+
|
106
|
+
@cache['NA'] = self.__init_eval_R__('NA')
|
107
|
+
@cache['NaN'] = self.__init_eval_R__('NaN')
|
108
|
+
# @cache['NAN'] = self.eval_R('as.double(NA)')
|
94
109
|
|
95
110
|
#help!
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
111
|
+
@cache['helpfun'] = self.with_mode(NO_CONVERSION, self.__getitem__('help',true))
|
112
|
+
end
|
113
|
+
|
114
|
+
#Delete an R object from the cache. Use R-style function naming, not ruby style.
|
115
|
+
def delete_from_cache(x)
|
116
|
+
@cache.delete(x)
|
117
|
+
end
|
102
118
|
|
119
|
+
def self.img(filename,args={})
|
120
|
+
format = File.extname(filename).gsub(".","").to_sym
|
121
|
+
r = RSRuby.instance
|
122
|
+
raise ArgumentError, "Format #{format.to_s} is not supported" unless [:pdf].include? format
|
123
|
+
r.pdf(filename,args)
|
124
|
+
yield(r)
|
125
|
+
r.dev_off.call
|
103
126
|
end
|
104
127
|
|
105
128
|
#Handles method name conversion and calling of R functions
|
@@ -193,15 +216,17 @@ class RSRuby
|
|
193
216
|
|
194
217
|
#Sets the default conversion mode for RSRuby. The constants defined
|
195
218
|
#in #RSRuby should be used
|
219
|
+
#DEPRECATED: Use the accessor instead
|
196
220
|
def RSRuby.set_default_mode(m)
|
197
221
|
if m < -1 or m > TOP_CONVERSION
|
198
222
|
raise ArgumentError, "Invalid mode requested"
|
199
223
|
end
|
200
|
-
|
224
|
+
RSRuby.instance.default_mode = m
|
201
225
|
end
|
202
226
|
#Returns the current default conversion mode as an Integer.
|
227
|
+
#DEPRECATED: Use the accessor on the RSRuby instance isntead
|
203
228
|
def RSRuby.get_default_mode
|
204
|
-
|
229
|
+
RSRuby.instance.default_mode
|
205
230
|
end
|
206
231
|
|
207
232
|
#TODO - not implemented
|
@@ -234,46 +259,38 @@ class RSRuby
|
|
234
259
|
@@rsruby_showfiles
|
235
260
|
end
|
236
261
|
|
237
|
-
#Returns the current class table Hash for RSRuby.
|
238
|
-
def class_table
|
239
|
-
@@class_table
|
240
|
-
end
|
241
|
-
|
242
|
-
#Sets the RSRuby class table Hash.
|
243
|
-
def class_table=(h)
|
244
|
-
@@class_table = h
|
245
|
-
end
|
246
|
-
|
247
|
-
#Returns the current proc table Hash for RSRuby.
|
248
|
-
def proc_table
|
249
|
-
@@proc_table
|
250
|
-
end
|
251
|
-
|
252
|
-
#Sets the RSRuby proc table Hash.
|
253
|
-
def proc_table=(h)
|
254
|
-
@@proc_table = h
|
255
|
-
end
|
256
|
-
|
257
262
|
#Evaluates the given string in R. Returns the result of the evaluation.
|
258
263
|
def eval_R(s)
|
259
264
|
self.eval(self.parse(:text => s))
|
260
265
|
end
|
261
266
|
|
267
|
+
|
262
268
|
#Wraps the R help function.
|
263
269
|
def help(*args)
|
264
|
-
helpobj =
|
270
|
+
helpobj = @cache['helpfun'].call(args)
|
265
271
|
self.print(helpobj)
|
266
272
|
end
|
267
273
|
|
268
|
-
|
274
|
+
|
275
|
+
def __init_eval_R__(s)
|
276
|
+
parsed = self.parse.__init_lcall__([['text',s]])
|
277
|
+
self.eval.__init_lcall__([['',parsed]])
|
278
|
+
end
|
279
|
+
|
280
|
+
def __getitem__(name,init=false)
|
269
281
|
|
270
282
|
#Find the identifier and cache (unless already cached)
|
271
|
-
unless
|
272
|
-
|
283
|
+
unless @cache.has_key?(name) && @caching
|
284
|
+
if init
|
285
|
+
robj = @cache['get'].__init_lcall__([['',name]])
|
286
|
+
else
|
287
|
+
robj = @cache['get'].lcall([['',name]])
|
288
|
+
end
|
289
|
+
@cache[name] = robj if @caching
|
273
290
|
end
|
274
291
|
|
275
292
|
#Retrieve object from cache
|
276
|
-
robj
|
293
|
+
robj ||= @cache[name]
|
277
294
|
|
278
295
|
return robj
|
279
296
|
|
data/lib/rsruby/dataframe.rb
CHANGED
@@ -55,12 +55,37 @@ class DataFrame < ERObj
|
|
55
55
|
#Returns an array of the column names used in the R data frame.
|
56
56
|
def columns
|
57
57
|
cols = @r.colnames(@robj)
|
58
|
-
cols = [cols] unless cols.
|
58
|
+
cols = [cols] unless cols.kind_of?(Array)
|
59
59
|
return cols
|
60
60
|
end
|
61
61
|
|
62
|
-
def[](col)
|
63
|
-
|
62
|
+
#def[](col)
|
63
|
+
# return @r['$'].call(@robj,col.to_s)
|
64
|
+
#end
|
65
|
+
|
66
|
+
#Needs to work for named and numbered columns
|
67
|
+
def[](row,col)
|
68
|
+
if col.kind_of?(Integer) and !(columns.include?(col))
|
69
|
+
col = columns[col]
|
70
|
+
end
|
71
|
+
return @r['$'].call(@robj,col.to_s)[row]
|
72
|
+
end
|
73
|
+
|
74
|
+
def[]=(row,col,val)
|
75
|
+
#How to set a value in this dataframe?
|
76
|
+
@r.assign("rsrubytemp",@robj)
|
77
|
+
|
78
|
+
### VERY HACKY - This relies on val having the same
|
79
|
+
#string representation in R and Ruby. An assign based
|
80
|
+
#solution with proper conversion of val would be much
|
81
|
+
#better
|
82
|
+
@r.eval_R("rsrubytemp[#{row+1},#{col+1}] <- #{val}")
|
83
|
+
#
|
84
|
+
#@r.assign("rsrubytemp[#{row+1},#{col+1}]",val)
|
85
|
+
|
86
|
+
@robj = @r.eval_R('get("rsrubytemp")')
|
87
|
+
|
88
|
+
return @r['$'].call(@robj,columns[col].to_s)[row]
|
64
89
|
end
|
65
90
|
|
66
91
|
def method_missing(attr)
|
data/test/tc_array.rb
CHANGED
@@ -4,8 +4,8 @@ require 'rsruby'
|
|
4
4
|
class TestArray < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def setup
|
7
|
-
|
8
7
|
@r = RSRuby.instance
|
8
|
+
#@r.gctorture(:on => false)
|
9
9
|
@ruby_AoA = [[[0,6,12,18],[2,8,14,20],[4,10,16,22]],
|
10
10
|
[[1,7,13,19],[3,9,15,21],[5,11,17,23]]]
|
11
11
|
|
@@ -16,6 +16,10 @@ class TestArray < Test::Unit::TestCase
|
|
16
16
|
@r.array.autoconvert(RSRuby::BASIC_CONVERSION)
|
17
17
|
end
|
18
18
|
|
19
|
+
def test_boolean
|
20
|
+
assert_equal [true,false], @r.c(true,false)
|
21
|
+
end
|
22
|
+
|
19
23
|
def test_convert_to_ruby
|
20
24
|
assert_equal(@ruby_AoA,@r_array.to_ruby)
|
21
25
|
end
|
data/test/tc_boolean.rb
CHANGED
@@ -6,6 +6,7 @@ class TestBoolean < Test::Unit::TestCase
|
|
6
6
|
def setup
|
7
7
|
@r = RSRuby.instance
|
8
8
|
RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
|
9
|
+
@r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
9
10
|
end
|
10
11
|
|
11
12
|
def test_true
|
@@ -21,4 +22,9 @@ class TestBoolean < Test::Unit::TestCase
|
|
21
22
|
@r.as_logical(@r.FALSE))
|
22
23
|
end
|
23
24
|
end
|
25
|
+
|
26
|
+
def test_boolean_array
|
27
|
+
assert_equal([true,false,true,false],@r.c(true,false,true,false))
|
28
|
+
end
|
29
|
+
|
24
30
|
end
|
data/test/tc_cleanup.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'rsruby'
|
3
|
-
|
3
|
+
|
4
4
|
class TestCleanup < Test::Unit::TestCase
|
5
5
|
|
6
6
|
def setup
|
@@ -8,13 +8,15 @@ class TestCleanup < Test::Unit::TestCase
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_shutdown
|
11
|
-
|
12
|
-
|
13
|
-
@r.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
#@r.eval_R("shutdown_test=10")
|
12
|
+
#@r.shutdown
|
13
|
+
#assert_raise(RException){ @r.eval_R("shutdown_test") }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_crash
|
17
|
+
#Signal.trap('BUS','EXIT')
|
18
|
+
#Signal.trap('BUS',proc{ puts 'hi there'; exit!})
|
19
|
+
#@r.crash
|
18
20
|
end
|
19
21
|
|
20
22
|
end
|
data/test/tc_eval.rb
CHANGED
data/test/tc_extensions.rb
CHANGED
@@ -2,7 +2,8 @@ require 'test/unit'
|
|
2
2
|
require 'rsruby'
|
3
3
|
|
4
4
|
class TestNewCases < Test::Unit::TestCase
|
5
|
-
|
5
|
+
@@test_dir = File.expand_path File.dirname(__FILE__)
|
6
|
+
|
6
7
|
def test_erobj
|
7
8
|
|
8
9
|
require 'rsruby/erobj'
|
@@ -19,8 +20,23 @@ class TestNewCases < Test::Unit::TestCase
|
|
19
20
|
|
20
21
|
def test_dataframe
|
21
22
|
|
23
|
+
require 'rsruby/dataframe'
|
22
24
|
r = RSRuby.instance
|
23
|
-
r.
|
25
|
+
r.class_table['data.frame'] = lambda{|x| DataFrame.new(x)}
|
26
|
+
RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
|
27
|
+
table = r.read_table(@@test_dir+"/table.txt",:header=>true)
|
28
|
+
assert_instance_of(DataFrame,table)
|
29
|
+
|
30
|
+
assert_equal(['A','B','C','D'],table.columns)
|
31
|
+
assert_equal([1,2,3],table.rows)
|
32
|
+
|
33
|
+
#assert_equal(['X1','X2','X3'],table['A'])
|
34
|
+
assert_equal('X2',table[1,'A'])
|
35
|
+
assert_equal('X2',table[1,0])
|
36
|
+
|
37
|
+
assert_equal(7,table[1,1])
|
38
|
+
table[1,1] = 5
|
39
|
+
assert_equal(5,table[1,1])
|
24
40
|
|
25
41
|
end
|
26
42
|
|
data/test/tc_init.rb
CHANGED
data/test/tc_matrix.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rsruby'
|
3
|
+
|
4
|
+
class Matrix
|
5
|
+
def as_r
|
6
|
+
"wibble"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class TestMatrix < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@r = RSRuby.instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_matrix_no_convert
|
17
|
+
r = RSRuby.instance
|
18
|
+
r.matrix.autoconvert(RSRuby::NO_CONVERSION)
|
19
|
+
m = r.matrix([1,2,3,4], :ncol => 2, :nrow => 2)
|
20
|
+
assert r.is_matrix(m)
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/test/tc_to_r.rb
CHANGED
@@ -17,6 +17,7 @@ class TestToR < Test::Unit::TestCase
|
|
17
17
|
|
18
18
|
def setup
|
19
19
|
@r = RSRuby.instance
|
20
|
+
#@r.gctorture(:on => true)
|
20
21
|
RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
|
21
22
|
end
|
22
23
|
|
@@ -88,6 +89,7 @@ class TestToR < Test::Unit::TestCase
|
|
88
89
|
def test_hash_to_named_vector
|
89
90
|
@r.c.autoconvert(RSRuby::NO_CONVERSION)
|
90
91
|
assert_equal(@r.typeof(@r.c(:foo => 5, :bar => 7)),'integer')
|
92
|
+
|
91
93
|
assert(@r.attributes(@r.c(:foo => 5, :bar => 7))['names'].include?('foo'))
|
92
94
|
assert(@r.attributes(@r.c(:foo => 5, :bar => 7))['names'].include?('bar'))
|
93
95
|
#TODO - these fail because of the different calling semantics in
|
@@ -113,7 +115,7 @@ class TestToR < Test::Unit::TestCase
|
|
113
115
|
def test_instances_not_convertible
|
114
116
|
foo = Foo.new
|
115
117
|
assert_raises(ArgumentError){@r.c(foo)}
|
116
|
-
|
118
|
+
end
|
117
119
|
|
118
120
|
def test_as_r_method
|
119
121
|
@r.c.autoconvert(RSRuby::BASIC_CONVERSION)
|
data/test/tc_to_ruby.rb
CHANGED
@@ -2,7 +2,8 @@ require 'test/unit'
|
|
2
2
|
require 'rsruby'
|
3
3
|
|
4
4
|
class TestToRuby < Test::Unit::TestCase
|
5
|
-
|
5
|
+
@@test_dir = File.expand_path File.dirname(__FILE__)
|
6
|
+
|
6
7
|
def setup
|
7
8
|
@r = RSRuby.instance
|
8
9
|
RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
|
@@ -70,7 +71,7 @@ class TestToRuby < Test::Unit::TestCase
|
|
70
71
|
#TODO - table.txt?????????
|
71
72
|
def test_dataframe_to_list
|
72
73
|
@r.read_table.autoconvert(RSRuby::BASIC_CONVERSION)
|
73
|
-
assert_equal(@r.read_table("
|
74
|
+
assert_equal(@r.read_table(@@test_dir+"/table.txt", {:header => 1}),
|
74
75
|
{
|
75
76
|
'A' => ['X1','X2','X3'],
|
76
77
|
'C' => [5,8,2],
|
data/test/test_all.rb
CHANGED
metadata
CHANGED
@@ -1,39 +1,38 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.2
|
3
|
-
specification_version: 1
|
4
2
|
name: rsruby
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-08-10 00:00:00 +09:00
|
8
|
-
summary: RSRuby is a bridge library for Ruby giving Ruby developers access to the full R statistical programming environment. RSRuby embeds a full R interpreter inside the running Ruby script, allowing R methods to be called and data passed between the Ruby script and the R interpreter. Most data conversion is handled automatically, but user-definable conversion routines can also be written to handle any R or Ruby class.
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
- test
|
12
|
-
email: alexg@kuicr.kyoto-u.ac.jp
|
13
|
-
homepage: http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/
|
14
|
-
rubyforge_project: rsruby
|
15
|
-
description: RSRuby is a bridge library for Ruby giving Ruby developers access to the full R statistical programming environment. RSRuby embeds a full R interpreter inside the running Ruby script, allowing R methods to be called and data passed between the Ruby script and the R interpreter. Most data conversion is handled automatically, but user-definable conversion routines can also be written to handle any R or Ruby class.
|
16
|
-
autorequire:
|
17
|
-
default_executable:
|
18
|
-
bindir: bin
|
19
|
-
has_rdoc: true
|
20
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
|
-
requirements:
|
22
|
-
- - ">"
|
23
|
-
- !ruby/object:Gem::Version
|
24
|
-
version: 0.0.0
|
25
|
-
version:
|
4
|
+
version: "0.5"
|
26
5
|
platform: ruby
|
27
|
-
signing_key:
|
28
|
-
cert_chain:
|
29
|
-
post_install_message:
|
30
6
|
authors:
|
31
7
|
- Alex Gutteridge
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-04-18 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: RSRuby is a bridge library for Ruby giving Ruby developers access to the full R statistical programming environment. RSRuby embeds a full R interpreter inside the running Ruby script, allowing R methods to be called and data passed between the Ruby script and the R interpreter. Most data conversion is handled automatically, but user-definable conversion routines can also be written to handle any R or Ruby class.
|
17
|
+
email: ag357@cam.ac.uk
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions:
|
21
|
+
- ext/extconf.rb
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.txt
|
24
|
+
- History.txt
|
25
|
+
- License.txt
|
26
|
+
- examples/arrayfields.rb
|
27
|
+
- examples/bioc.rb
|
28
|
+
- examples/dataframe.rb
|
29
|
+
- examples/erobj.rb
|
32
30
|
files:
|
33
31
|
- History.txt
|
34
32
|
- License.txt
|
35
33
|
- Manifest.txt
|
36
34
|
- README.txt
|
35
|
+
- Rakefile.rb
|
37
36
|
- examples/arrayfields.rb
|
38
37
|
- examples/bioc.rb
|
39
38
|
- examples/dataframe.rb
|
@@ -59,6 +58,7 @@ files:
|
|
59
58
|
- test/tc_init.rb
|
60
59
|
- test/tc_io.rb
|
61
60
|
- test/tc_library.rb
|
61
|
+
- test/tc_matrix.rb
|
62
62
|
- test/tc_modes.rb
|
63
63
|
- test/tc_robj.rb
|
64
64
|
- test/tc_sigint.rb
|
@@ -67,27 +67,37 @@ files:
|
|
67
67
|
- test/tc_util.rb
|
68
68
|
- test/tc_vars.rb
|
69
69
|
- test/test_all.rb
|
70
|
-
|
71
|
-
-
|
70
|
+
has_rdoc: true
|
71
|
+
homepage: http://web.kuicr.kyoto-u.ac.jp/~alexg/rsruby/
|
72
|
+
post_install_message:
|
72
73
|
rdoc_options:
|
73
74
|
- --exclude
|
74
75
|
- test/*
|
75
76
|
- --main
|
76
77
|
- README.txt
|
77
78
|
- --inline-source
|
78
|
-
|
79
|
-
-
|
80
|
-
-
|
81
|
-
-
|
82
|
-
|
83
|
-
|
84
|
-
-
|
85
|
-
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
- test
|
82
|
+
- ext
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "0"
|
94
|
+
version:
|
90
95
|
requirements: []
|
91
96
|
|
92
|
-
|
93
|
-
|
97
|
+
rubyforge_project: rsruby
|
98
|
+
rubygems_version: 1.1.0
|
99
|
+
signing_key:
|
100
|
+
specification_version: 2
|
101
|
+
summary: RSRuby is a bridge library for Ruby giving Ruby developers access to the full R statistical programming environment. RSRuby embeds a full R interpreter inside the running Ruby script, allowing R methods to be called and data passed between the Ruby script and the R interpreter. Most data conversion is handled automatically, but user-definable conversion routines can also be written to handle any R or Ruby class.
|
102
|
+
test_files:
|
103
|
+
- test/test_all.rb
|