rsruby 0.4.0

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.
@@ -0,0 +1,97 @@
1
+ #== Synopsis
2
+ #
3
+ #This is an extended #RObj class inspired by the example given in the RPy
4
+ #manual. Methods caught by method_missing are converted into attribute calls
5
+ #on the R object it represents. Also to_s is redefined to print exactly the
6
+ #representation used in R
7
+ #
8
+ #== Usage
9
+ #
10
+ #See examples/erobj.rb for examples of usage.
11
+ #
12
+ #--
13
+ # == Author
14
+ # Alex Gutteridge
15
+ #
16
+ # == Copyright
17
+ #Copyright (C) 2006 Alex Gutteridge
18
+ #
19
+ # The Original Code is the RPy python module.
20
+ #
21
+ # The Initial Developer of the Original Code is Walter Moreira.
22
+ # Portions created by the Initial Developer are Copyright (C) 2002
23
+ # the Initial Developer. All Rights Reserved.
24
+ #
25
+ # Contributor(s):
26
+ # Gregory R. Warnes <greg@warnes.net> (RPy Maintainer)
27
+ #
28
+ #This library is free software; you can redistribute it and/or
29
+ #modify it under the terms of the GNU Lesser General Public
30
+ #License as published by the Free Software Foundation; either
31
+ #version 2.1 of the License, or (at your option) any later version.
32
+ #
33
+ #This library is distributed in the hope that it will be useful,
34
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36
+ #Lesser General Public License for more details.
37
+ #
38
+ #You should have received a copy of the GNU Lesser General Public
39
+ #License along with this library; if not, write to the Free Software
40
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
41
+ #++
42
+
43
+ require 'rsruby'
44
+
45
+ class ERObj
46
+
47
+ @@x = 1
48
+
49
+ #Requires an RObj for intialization.
50
+ def initialize(robj)
51
+ @robj = robj
52
+ @r = RSRuby.instance
53
+ end
54
+
55
+ #Returns the wrapped RObj when RSRuby attempts to convert it to
56
+ #R.
57
+ def as_r
58
+ @robj.as_r
59
+ end
60
+
61
+ #Calls the wrapped RObj.
62
+ def lcall(args)
63
+ @robj.lcall(args)
64
+ end
65
+
66
+ #Outputs the string representation provided by R.
67
+ def to_s
68
+
69
+ @@x += 1
70
+
71
+ mode = RSRuby.get_default_mode
72
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
73
+ a = @r.textConnection("tmpobj#{@@x}",'w')
74
+
75
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
76
+ @r.sink(:file => a, :type => 'output')
77
+ @r.print_(@robj)
78
+ @r.sink.call()
79
+ @r.close_connection(a)
80
+
81
+ str = @r["tmpobj#{@@x}"].join("\n")
82
+
83
+ RSRuby.set_default_mode(mode)
84
+
85
+ return str
86
+
87
+ end
88
+
89
+ def method_missing(attr)
90
+ mode = RSRuby.get_default_mode
91
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
92
+ e = @r['$'].call(@robj,attr.to_s)
93
+ RSRuby.set_default_mode(mode)
94
+ return e
95
+ end
96
+
97
+ end
@@ -0,0 +1,58 @@
1
+ #== Synopsis
2
+ #
3
+ #This class represents a reference to an object in the R interpreter. It
4
+ #also holds a conversion mode used if the RObj represents a callable function.
5
+ #RObj objects can be passed to R functions called from Ruby and are the
6
+ #default return type if rsruby cannot convert the returned results of an R
7
+ #function.
8
+ #
9
+ #--
10
+ # == Author
11
+ # Alex Gutteridge
12
+ #
13
+ # == Copyright
14
+ #Copyright (C) 2006 Alex Gutteridge
15
+ #
16
+ #This library is free software; you can redistribute it and/or
17
+ #modify it under the terms of the GNU Lesser General Public
18
+ #License as published by the Free Software Foundation; either
19
+ #version 2.1 of the License, or (at your option) any later version.
20
+ #
21
+ #This library is distributed in the hope that it will be useful,
22
+ #but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+ #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24
+ #Lesser General Public License for more details.
25
+ #
26
+ #You should have received a copy of the GNU Lesser General Public
27
+ #License along with this library; if not, write to the Free Software
28
+ #Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29
+ #++
30
+
31
+ class RObj
32
+
33
+ attr_accessor :conversion, :wrap
34
+
35
+ :private
36
+ def call(*args)
37
+ if @wrap
38
+ e = RSRuby.get_default_mode
39
+ RSRuby.set_default_mode(@wrap)
40
+ ret = self.lcall(RSRuby.convert_args_to_lcall(args))
41
+ RSRuby.set_default_mode(e)
42
+ else
43
+ ret = self.lcall(RSRuby.convert_args_to_lcall(args))
44
+ end
45
+ return ret
46
+ end
47
+
48
+ def autoconvert(m=false)
49
+ if m
50
+ raise ArgumentError if m < -1 or m > RSRuby::TOP_CONVERSION
51
+ @conversion = m
52
+ end
53
+ @conversion
54
+ end
55
+
56
+ end
57
+
58
+
data/test/tc_array.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestArray < Test::Unit::TestCase
9
+
10
+ def setup
11
+
12
+ @ruby_AoA = [[[0,6,12,18],[2,8,14,20],[4,10,16,22]],
13
+ [[1,7,13,19],[3,9,15,21],[5,11,17,23]]]
14
+
15
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
16
+ $r.array.autoconvert(RSRuby::NO_CONVERSION)
17
+ @r_array = $r.array({ :data => (0..24).to_a,
18
+ :dim => [2,3,4]})
19
+ $r.array.autoconvert(RSRuby::BASIC_CONVERSION)
20
+ end
21
+
22
+ def test_convert_to_ruby
23
+ assert_equal(@ruby_AoA,@r_array.to_ruby)
24
+ end
25
+
26
+ #I suspect this only works in RPy with Numeric?
27
+ def test_convert_to_R
28
+ $r.list.autoconvert(RSRuby::NO_CONVERSION)
29
+ $r['[['].autoconvert(RSRuby::NO_CONVERSION)
30
+ o = $r['[['].call($r.list(@ruby_AoA),1)
31
+ $r['[['].autoconvert(RSRuby::BASIC_CONVERSION)
32
+ #assert_equal($r.all_equal(o,@r_array),true)
33
+ end
34
+
35
+ def test_dimensions
36
+ assert_equal($r.dim(@r_array),[@ruby_AoA.length,
37
+ @ruby_AoA[0].length,
38
+ @ruby_AoA[0][0].length])
39
+ end
40
+
41
+ def test_elements
42
+ assert_equal(@ruby_AoA[0][0][0],$r['[['].call(@r_array, 1,1,1))
43
+ assert_equal(@ruby_AoA[1][1][1],$r['[['].call(@r_array, 2,2,2))
44
+ end
45
+
46
+ def test_ruby_out_of_bounds
47
+ assert_raise NoMethodError do
48
+ @ruby_AoA[5][5][5]
49
+ end
50
+ end
51
+
52
+ def test_R_out_of_bounds
53
+ assert_raise RException do
54
+ $r['[['].call(@r_array, 5,5,5)
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,27 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestBoolean < Test::Unit::TestCase
9
+
10
+ def setup
11
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
12
+ end
13
+
14
+ def test_true
15
+ assert_block "r.TRUE not working" do
16
+ ($r.typeof($r.FALSE) == 'logical' and
17
+ $r.as_logical($r.TRUE))
18
+ end
19
+ end
20
+
21
+ def test_false
22
+ assert_block "r.FALSE not working" do
23
+ ($r.typeof($r.FALSE) == 'logical' and not
24
+ $r.as_logical($r.FALSE))
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestCleanup < Test::Unit::TestCase
9
+
10
+ def test_shutdown
11
+ #TODO - shutdown doesn't really seem to do anything???
12
+ $r.shutdown
13
+ assert $r.nil?
14
+ $r = RSRuby.instance()
15
+ end
16
+
17
+ def test_restart
18
+ $r.shutdown
19
+ $r = RSRuby.instance()
20
+ assert $r
21
+ end
22
+ end
data/test/tc_eval.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ class TestEval < Test::Unit::TestCase
5
+
6
+ def test_eval_R
7
+ #Test integer, Float, String and Boolean return values
8
+ assert_equal($r.eval_R("sum(1,2,3)"),6)
9
+ assert_equal($r.eval_R("sum(1.5,2.5,3.5)"),7.5)
10
+ assert_equal($r.eval_R("eval('R')"),"R")
11
+ assert_equal($r.eval_R("is(1,'numeric')"),true)
12
+ assert_equal($r.eval_R("is(1,'madeup')"),false)
13
+ end
14
+
15
+ end
data/test/tc_init.rb ADDED
File without changes
data/test/tc_io.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class DummyIO
9
+ def write
10
+ end
11
+ end
12
+
13
+ class TestIO < Test::Unit::TestCase
14
+
15
+ def setup
16
+ $stdout = $stderr = DummyIO.new
17
+ end
18
+
19
+ def teardown
20
+ $stdout = STDOUT
21
+ $stderr = STDERR
22
+ end
23
+
24
+ def test_io_stdin
25
+ dummy = lambda{|prompt,n| prompt+'\n'}
26
+ $r.set_rsruby_input(dummy)
27
+ assert $r.readline('foo') == 'foo'
28
+ end
29
+
30
+ def test_io_stdout
31
+ out = []
32
+ dummy = lambda{|string| out.push(string)}
33
+ $r.set_rsruby_output(dummy)
34
+ $r.print(5)
35
+ assert out == ['[1]','5','\n']
36
+ end
37
+
38
+ def test_io_showfiles
39
+ out = []
40
+ dummy = lambda{|files,headers,title,delete|
41
+ out.push('foo')
42
+ }
43
+ $r.set_rsruby_showfiles(dummy)
44
+ $r.help()
45
+ assert out == ['foo']
46
+ end
47
+
48
+ def test_io_stdout_exception
49
+ #TODO - I can't understand this test in Rpy
50
+ end
51
+
52
+ def test_io_stdin_exception
53
+ #TODO - I can't understand this test in Rpy
54
+ end
55
+
56
+ def test_io_stderr_exception
57
+ #TODO - I can't understand this test in Rpy
58
+ end
59
+
60
+ end
@@ -0,0 +1,20 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestLibrary < Test::Unit::TestCase
9
+
10
+ def test_library
11
+ #Test success
12
+ assert_nothing_raised(){$r.library("boot")}
13
+ end
14
+
15
+ def test_library_fail
16
+ #Test failure
17
+ assert_raises(RException){$r.library("Missing")}
18
+ end
19
+
20
+ end
data/test/tc_modes.rb ADDED
@@ -0,0 +1,212 @@
1
+ require 'test/unit'
2
+ require 'rsruby'
3
+
4
+ unless $r
5
+ $r = RSRuby.instance
6
+ end
7
+
8
+ class TestModes < Test::Unit::TestCase
9
+
10
+ def setup
11
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
12
+ $r.class_table.clear
13
+ $r.proc_table.clear
14
+ end
15
+
16
+ def test_to_ruby_args
17
+ assert_raises(ArgumentError){$r.seq.to_ruby(RSRuby::TOP_CONVERSION+1)}
18
+ assert_raises(ArgumentError){$r.seq.to_ruby(-2)}
19
+ assert_raises(TypeError){$r.seq.to_ruby('foo')}
20
+ end
21
+
22
+ def test_to_ruby
23
+ $r.c.autoconvert(RSRuby::NO_CONVERSION)
24
+ four = $r.c(4)
25
+ assert_equal(four.to_ruby, 4)
26
+ assert_equal(four.to_ruby(RSRuby::PROC_CONVERSION), 4)
27
+ assert_equal(four.to_ruby(RSRuby::BASIC_CONVERSION), 4)
28
+ assert_equal(four.to_ruby(RSRuby::VECTOR_CONVERSION), [4])
29
+ assert($r["=="].call(four.to_ruby(RSRuby::NO_CONVERSION),four))
30
+ end
31
+
32
+ def test_to_ruby_default_arg
33
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
34
+ sequence = $r.seq(1,3)
35
+ t_test = $r.t_test([1,2,3])
36
+
37
+ assert_equal(sequence.to_ruby.class , RObj)
38
+ assert_equal(sequence.to_ruby.class, sequence.class)
39
+
40
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
41
+ assert_equal(sequence.to_ruby, [1,2,3])
42
+
43
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
44
+ assert_equal(sequence.to_ruby, [1,2,3])
45
+
46
+ $r.class_table['htest'] = lambda{5}
47
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
48
+ assert_equal(t_test.to_ruby, 5)
49
+
50
+ $r.proc_table[lambda{true}] = lambda{return 6}
51
+ RSRuby.set_default_mode(RSRuby::PROC_CONVERSION)
52
+ assert_equal(t_test.to_ruby, 6)
53
+ end
54
+
55
+ def test_default_modes
56
+ RSRuby.set_default_mode(RSRuby::PROC_CONVERSION)
57
+ assert_equal(RSRuby.get_default_mode, RSRuby::PROC_CONVERSION)
58
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
59
+ assert_equal(RSRuby.get_default_mode, RSRuby::CLASS_CONVERSION)
60
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
61
+ assert_equal(RSRuby.get_default_mode, RSRuby::BASIC_CONVERSION)
62
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
63
+ assert_equal(RSRuby.get_default_mode, RSRuby::VECTOR_CONVERSION)
64
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
65
+ assert_equal(RSRuby.get_default_mode, RSRuby::NO_CONVERSION)
66
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
67
+ assert_equal(RSRuby.get_default_mode, RSRuby::NO_DEFAULT)
68
+ end
69
+
70
+ def test_bad_modes
71
+ assert_raises(ArgumentError){RSRuby.set_default_mode(-2)}
72
+ assert_raises(ArgumentError){RSRuby.set_default_mode(RSRuby::TOP_CONVERSION+1)}
73
+ end
74
+
75
+ def test_no_default_mode
76
+ $r.t_test.autoconvert(RSRuby::CLASS_CONVERSION)
77
+ $r.array.autoconvert(RSRuby::NO_CONVERSION)
78
+ $r.seq.autoconvert(RSRuby::BASIC_CONVERSION)
79
+
80
+ assert_equal($r.array(1,3).class, $r.array.class)
81
+
82
+ assert_equal($r.seq(1,3), [1,2,3])
83
+ $r.class_table['htest'] = lambda{5}
84
+ assert_equal($r.t_test([1,2,3]), 5)
85
+ end
86
+
87
+ def test_individual_conversions
88
+ $r.c.autoconvert(RSRuby::BASIC_CONVERSION)
89
+ $r.seq.autoconvert(RSRuby::PROC_CONVERSION)
90
+ $r.min.autoconvert(RSRuby::VECTOR_CONVERSION)
91
+
92
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
93
+ assert_equal($r.c(4).class, RObj)
94
+ assert_equal($r.seq(1,3).class, RObj)
95
+ assert_equal($r.min(1,3).class, RObj)
96
+
97
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
98
+ assert_equal($r.c.autoconvert, RSRuby::BASIC_CONVERSION)
99
+ assert_equal($r.seq.autoconvert, RSRuby::PROC_CONVERSION)
100
+ assert_equal($r.min.autoconvert, RSRuby::VECTOR_CONVERSION)
101
+ assert_equal($r.c(4), 4)
102
+ assert_equal($r.seq(1,3), [1,2,3])
103
+ assert_equal($r.min(1,3), [1])
104
+
105
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
106
+ assert_equal($r.c.autoconvert, RSRuby::BASIC_CONVERSION)
107
+ assert_equal($r.seq.autoconvert, RSRuby::PROC_CONVERSION)
108
+ assert_equal($r.min.autoconvert, RSRuby::VECTOR_CONVERSION)
109
+ assert_equal($r.c(4), 4)
110
+ assert_equal($r.seq(1,3), [1,2,3])
111
+ assert_equal($r.min(1,3), 1)
112
+
113
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
114
+ assert_equal($r.c.autoconvert, RSRuby::BASIC_CONVERSION)
115
+ assert_equal($r.seq.autoconvert, RSRuby::PROC_CONVERSION)
116
+ assert_equal($r.min.autoconvert, RSRuby::VECTOR_CONVERSION)
117
+ assert_equal($r.c(4), [4])
118
+ assert_equal($r.seq(1,3), [1,2,3])
119
+ assert_equal($r.min(1,3), [1])
120
+
121
+ end
122
+
123
+ def test_vector_conversion
124
+
125
+ RSRuby.set_default_mode(RSRuby::VECTOR_CONVERSION)
126
+
127
+ assert_equal($r.c(true), [true])
128
+ assert_equal($r.c(4) , [4])
129
+ assert_equal($r.c('A') , ['A'])
130
+
131
+ assert_equal($r.c(1,'A',2), ['1','A','2'])
132
+ assert_equal($r.c(:a => 1, :b => 'A', :c => 2), {'a' => '1', 'b' => 'A', 'c' => '2'})
133
+ assert_equal($r.list(:a => 1, :b => 'A', :c => 2),
134
+ {'a' => [1], 'b' => ['A'], 'c' => [2]})
135
+ assert_equal($r.eval_R("x~y").class, RObj)
136
+ end
137
+
138
+ def test_basic_conversion
139
+
140
+ RSRuby.set_default_mode(RSRuby::BASIC_CONVERSION)
141
+ assert_equal($r.c(true), true)
142
+ assert_equal($r.c(4), 4)
143
+ assert_equal($r.c('A') , 'A')
144
+
145
+ assert_equal($r.c(1,'A',2), ['1','A','2'])
146
+ assert_equal($r.c(:a => 1, :b => 'A', :c => 2), {'a' => '1', 'b' => 'A', 'c' => '2'})
147
+ assert_equal($r.list(:a => 1, :b => 'A', :c => 2),
148
+ {'a' => 1, 'b' => 'A', 'c' => 2})
149
+ assert_equal($r.eval_R("x~y").class, RObj)
150
+
151
+ end
152
+
153
+ def test_class_table
154
+
155
+ $r.class_table['htest'] = lambda{'htest'}
156
+ $r.class_table['data.frame'] = lambda{|x|
157
+ if $r['[['].call(x,1).length > 2
158
+ return 5
159
+ else
160
+ return 'bar'
161
+ end
162
+ }
163
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
164
+ assert_equal($r.t_test([1,2,3]), 'htest')
165
+ assert_equal($r.as_data_frame([1,2,3]), 5)
166
+ assert_equal($r.as_data_frame([1,2]), 'bar')
167
+
168
+ end
169
+
170
+ def test_multiple_class_table
171
+
172
+ RSRuby.set_default_mode(RSRuby::NO_CONVERSION)
173
+ f = $r.class__($r.c(4),'foo')
174
+ g = $r.class__($r.c(4), ['bar','foo'])
175
+
176
+ $r.class_table['foo'] = lambda{'foo'}
177
+ $r.class_table['bar'] = lambda{'bar'}
178
+ $r.class_table[['bar','foo']] = lambda{5}
179
+
180
+ RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)
181
+ assert_equal(f.to_ruby, 'foo')
182
+ assert_equal(g.to_ruby, 5)
183
+
184
+ $r.class_table.delete(['bar','foo'])
185
+ assert_equal(g.to_ruby, 'bar')
186
+
187
+ $r.class_table.delete('bar')
188
+ assert_equal(g.to_ruby, 'foo')
189
+
190
+ end
191
+
192
+ def test_proc_table
193
+
194
+ t = lambda{|x|
195
+ e = $r.attr(x,'names')
196
+ return false if e.nil?
197
+ if e == 'alternative' or e.include?('alternative')
198
+ return true
199
+ else
200
+ return false
201
+ end
202
+ }
203
+ f = lambda{|x| $r['$'].call(x,'alternative')}
204
+
205
+ $r.proc_table[t] = f
206
+ RSRuby.set_default_mode(RSRuby::NO_DEFAULT)
207
+ $r.t_test.autoconvert(RSRuby::PROC_CONVERSION)
208
+ assert_equal($r.t_test([1,2,3]), 'two.sided')
209
+
210
+ end
211
+
212
+ end