rsruby 0.4.5 → 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|