r_bridge 0.5.1 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -4
- data/ext/r_bridge/r_embed.c +34 -4
- data/ext/r_bridge/r_lang.c +16 -1
- data/lib/r_bridge/r_bridge_ffi.rb +75 -11
- data/lib/r_bridge/r_bridge_lazyfunc_ext.rb +106 -27
- data/lib/r_bridge/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad1d735bada2b3edde78582804db6ed1c260663f59fb52e236adf678248b75d7
|
4
|
+
data.tar.gz: 619abe8dc2e78aa7fae3d20c68da7279a67b72a4fe934562e6ef8d613cadb14b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da62f2782de29b146aa36909f9ddf40d4135379535a5a885abb6a1e50a981218d066d9f0dc444f8e7a678f1cac85375ba3385ace6bbc48be5ad37ef5c9fc29f5
|
7
|
+
data.tar.gz: c05bc29469b5b61629ef4e0575efae12f99a665fdba8df9f23d4f8106de83aa52b3b2fc124c741de525ab9e234c4b599dded80597ebe9824ddd7f2786dd606c6
|
data/README.md
CHANGED
@@ -216,12 +216,17 @@ RBridge.create_extptr( ffi_ptr )
|
|
216
216
|
|
217
217
|
* Create R function call
|
218
218
|
|
219
|
-
create_function_call
|
219
|
+
create_ns_function_call, create_env_function_call and create_function_call create R's internal S expresion structures for function calls. create_ns_function_call can specify (package) namespace. create_env_function_call can specify environment name.
|
220
|
+
|
221
|
+
Arguments are passed as Ruby's Hash like objects, Hash or assocation Array, and their each element's value needs to be R's object. For these R objects You can assign not only R vectors but also other function calls.
|
222
|
+
|
223
|
+
Assocation Arrays are useful when you have more than one elements with the same key name, which Hash does not allow. This happens when you do not specify parameter name and you use empty Strings, "", as parameter names.
|
220
224
|
|
221
|
-
Arguments are passed to the second argument as Ruby Hash, and each Hash's value needs to point to R's object. You usually pass R vectors, but you can also pass another function call as an argument.
|
222
225
|
|
223
226
|
```
|
224
|
-
RBridge.
|
227
|
+
RBridge.create_ns_function_call( ns, fname, hash_like )
|
228
|
+
RBridge.create_env_function_call( env, fname, hash_like )
|
229
|
+
RBridge.create_function_call( fname, hash_like )
|
225
230
|
|
226
231
|
(e.g.)
|
227
232
|
# pass vector to argument
|
@@ -231,6 +236,25 @@ RBridge.exec_function_no_return(hellowrold)
|
|
231
236
|
# pass another function call to argument
|
232
237
|
getwd = RBridge.create_function_call( "print", { "x" => RBridge.create_function_call( "getwd", {} ) } )
|
233
238
|
RBridge.exec_function_no_return(getwd)
|
239
|
+
|
240
|
+
# call sqrt function in base package.
|
241
|
+
ivec = RBridge.create_intvec([1,2,3])
|
242
|
+
calc = RBridge.create_ns_function_call( "base","sqrt", {"x" => ivec} )
|
243
|
+
RBridge.exec_function_no_return( RBridge.create_function_call( "print", {"" => calc} )) # execute & print out
|
244
|
+
|
245
|
+
# Call function in environment
|
246
|
+
#
|
247
|
+
# (e.g.) source the following newenv.R and call the newenv$hello function.
|
248
|
+
# # newenv.R
|
249
|
+
# newenv = new.env()
|
250
|
+
# newenv$hello = function(){ print("Hello!") }
|
251
|
+
#
|
252
|
+
RBridge.exec_function_no_return( RBridge.create_function_call("source", { "" => RBridge.create_strvec(["newenv.R"]) }))
|
253
|
+
RBridge.exec_function_no_return( RBridge.create_env_function_call("newenv", "hello", { } ))
|
254
|
+
|
255
|
+
# pass association Array to argument
|
256
|
+
add = RBridge.create_function_call( "+", [["" , RBridge.create_intvec( [1,2,3] )],["", RBridge.create_intvec( [10,20,30] ) ]] )
|
257
|
+
RBridge.exec_function( RBridge.create_function_call("print", [["" , add ]]))
|
234
258
|
```
|
235
259
|
|
236
260
|
The followings are utility functions. assign() and library() are frequently used in R, and easy ways to create them are provided.
|
@@ -356,7 +380,7 @@ RBridge.end_embedded_r()
|
|
356
380
|
|
357
381
|
## Additional Features
|
358
382
|
|
359
|
-
* LazyFunc + RParamManager (+ RResultManager): In contrast to create_function_call(),
|
383
|
+
* LazyFunc + RParamManager (+ RResultManager): In contrast to create_function_call(), create_lazy_function(), which creates LazyFunc object, does not need to take existent R objects. It can take RParamName, RResultName and so on, which are not associated with R objects until the function is evaluated. create_ns_lazy_function(), create_env_lazy_function() are lazy evaluation version of create_ns_function_call() and create_env_function_call(), which respectively allows specifying namespaces and environments.
|
360
384
|
|
361
385
|
These features are being developed for StatSailr, and the API is not stable. They can be accessed but they are not recommended for general usage.
|
362
386
|
|
data/ext/r_bridge/r_embed.c
CHANGED
@@ -2,25 +2,55 @@
|
|
2
2
|
#include <Rembedded.h>
|
3
3
|
#include <Rdefines.h>
|
4
4
|
|
5
|
+
#include <stdbool.h>
|
6
|
+
|
7
|
+
#include <stdint.h>
|
8
|
+
#define CSTACK_DEFNS
|
9
|
+
#include <Rinterface.h>
|
10
|
+
|
5
11
|
#include "win_compat.h"
|
6
12
|
|
13
|
+
#ifdef __FreeBSD__
|
14
|
+
#include <ieeefp.h>
|
15
|
+
fp_rnd_t fpmask_preset;
|
16
|
+
#endif
|
17
|
+
|
7
18
|
EXPORT void
|
8
|
-
r_embedded_init()
|
19
|
+
r_embedded_init( bool unlimited_stack_size )
|
9
20
|
{
|
10
|
-
|
11
|
-
|
21
|
+
|
22
|
+
#ifdef __FreeBSD__
|
23
|
+
fpmask_preset = fpsetmask(0);
|
24
|
+
#endif
|
25
|
+
|
26
|
+
size_t localArgc = 3;
|
27
|
+
char localArgs[][50] = {"R", "--silent", "--vanilla"};
|
12
28
|
|
13
29
|
char *args[ localArgc ];
|
14
30
|
for (size_t i = 0; i < localArgc; ++i){
|
15
31
|
args[i] = localArgs[i];
|
16
32
|
}
|
17
33
|
|
18
|
-
Rf_initEmbeddedR
|
34
|
+
// Rf_initEmbeddedR raises C stack usage limit error on multithreading environment.
|
35
|
+
// Rf_initEmbeddedR( localArgc , args ); is replaced with the following code.
|
36
|
+
|
37
|
+
if( unlimited_stack_size == false ){ // default stack size
|
38
|
+
Rf_initialize_R( localArgc , args );
|
39
|
+
setup_Rmainloop();
|
40
|
+
}else{
|
41
|
+
Rf_initialize_R( localArgc , args );
|
42
|
+
R_CStackLimit = (uintptr_t) -1 ; // Set -1 for unlimited C stack size.
|
43
|
+
setup_Rmainloop();
|
44
|
+
}
|
19
45
|
}
|
20
46
|
|
21
47
|
EXPORT void
|
22
48
|
r_embedded_end()
|
23
49
|
{
|
24
50
|
Rf_endEmbeddedR(0);
|
51
|
+
|
52
|
+
#ifdef __FreeBSD__
|
53
|
+
fpsetmask(fpmask_preset);
|
54
|
+
#endif
|
25
55
|
}
|
26
56
|
|
data/ext/r_bridge/r_lang.c
CHANGED
@@ -4,6 +4,22 @@
|
|
4
4
|
|
5
5
|
#include "win_compat.h"
|
6
6
|
|
7
|
+
EXPORT SEXP
|
8
|
+
r_lang_create_ns_fcall( const char* ns, const char* fname, SEXP args)
|
9
|
+
{
|
10
|
+
SEXP func;
|
11
|
+
PROTECT( func = LCONS( LCONS( Rf_install("::"), LCONS( Rf_install(ns), LCONS( Rf_install(fname), R_NilValue))) , args ));
|
12
|
+
return func;
|
13
|
+
}
|
14
|
+
|
15
|
+
EXPORT SEXP
|
16
|
+
r_lang_create_env_fcall( const char* env, const char* fname, SEXP args)
|
17
|
+
{
|
18
|
+
SEXP func;
|
19
|
+
PROTECT( func = LCONS( LCONS( Rf_install("$"), LCONS( Rf_install(env), LCONS( Rf_install(fname), R_NilValue))) , args ));
|
20
|
+
return func;
|
21
|
+
}
|
22
|
+
|
7
23
|
EXPORT SEXP
|
8
24
|
r_lang_create_fcall( const char* fname, SEXP args)
|
9
25
|
{
|
@@ -12,7 +28,6 @@ r_lang_create_fcall( const char* fname, SEXP args)
|
|
12
28
|
return func;
|
13
29
|
}
|
14
30
|
|
15
|
-
|
16
31
|
EXPORT SEXP
|
17
32
|
r_lang_cons( SEXP car, SEXP cdr)
|
18
33
|
{
|
@@ -7,7 +7,7 @@ module RBridge
|
|
7
7
|
lib_name = "librbridge" + "." + RbConfig::CONFIG['DLEXT']
|
8
8
|
ffi_lib File.expand_path( lib_name, __dir__ )
|
9
9
|
|
10
|
-
attach_function :r_embedded_init, [], :void
|
10
|
+
attach_function :r_embedded_init, [:bool], :void
|
11
11
|
attach_function :r_embedded_end, [], :void
|
12
12
|
|
13
13
|
attach_function :r_vec_create_str, [:int], :pointer
|
@@ -24,6 +24,8 @@ module RBridge
|
|
24
24
|
attach_function :r_list_to_dataframe, [:pointer ], :pointer
|
25
25
|
attach_function :r_dataframe_set_rownames, [:pointer, :pointer], :void
|
26
26
|
|
27
|
+
attach_function :r_lang_create_ns_fcall, [:string, :string, :pointer], :pointer
|
28
|
+
attach_function :r_lang_create_env_fcall, [:string, :string, :pointer], :pointer
|
27
29
|
attach_function :r_lang_create_fcall, [:string, :pointer], :pointer
|
28
30
|
attach_function :r_lang_cons, [:pointer, :pointer], :pointer
|
29
31
|
attach_function :r_lang_cons_gen, [:pointer], :pointer
|
@@ -47,8 +49,11 @@ module RBridge
|
|
47
49
|
|
48
50
|
# From here, Ruby interface
|
49
51
|
|
50
|
-
def self.init_embedded_r()
|
51
|
-
|
52
|
+
def self.init_embedded_r( unlimited_cstack: false )
|
53
|
+
if(unlimited_cstack.class != TrueClass && unlimited_cstack.class != FalseClass)
|
54
|
+
raise "init_embedded_r() can take true or false for unlimited C stack size. true: unlimited, false: default."
|
55
|
+
end
|
56
|
+
r_embedded_init( unlimited_cstack )
|
52
57
|
end
|
53
58
|
|
54
59
|
def self.end_embedded_r()
|
@@ -256,6 +261,8 @@ module RBridge
|
|
256
261
|
else
|
257
262
|
r_obj = value.to_r_symbol
|
258
263
|
end
|
264
|
+
when value.class == NilClass
|
265
|
+
r_obj = RBridge.r_nil
|
259
266
|
end
|
260
267
|
return r_obj
|
261
268
|
end
|
@@ -272,6 +279,10 @@ module RBridge
|
|
272
279
|
return new_lcons
|
273
280
|
end
|
274
281
|
|
282
|
+
def self.r_nil()
|
283
|
+
return r_lang_nil()
|
284
|
+
end
|
285
|
+
|
275
286
|
def self.is_r_nil?( obj )
|
276
287
|
result = r_is_nil( obj )
|
277
288
|
if(result == 1)
|
@@ -294,21 +305,44 @@ module RBridge
|
|
294
305
|
return extptr
|
295
306
|
end
|
296
307
|
|
297
|
-
def self.
|
298
|
-
|
299
|
-
|
300
|
-
|
308
|
+
def self.array_depth (ary)
|
309
|
+
return 0 unless ary.is_a?(Array)
|
310
|
+
return 1 + ary.map(){|elem| array_depth(elem) }.max()
|
311
|
+
end
|
312
|
+
|
313
|
+
def self.assoc_array?(ary)
|
314
|
+
if ary.map(){|elem| elem.size }.uniq == [2]
|
315
|
+
true
|
316
|
+
else
|
317
|
+
false
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
def self.hash_to_lcons_args( hash_like )
|
322
|
+
if hash_like.class == Hash
|
323
|
+
# hash
|
324
|
+
elsif hash_like.class == Array
|
325
|
+
if array_depth(hash_like) == 2 && assoc_array?(hash_like)
|
326
|
+
# association array
|
327
|
+
else
|
328
|
+
raise "hash_to_lcons_args should take Hash argument (or Association Array argument)"
|
329
|
+
end
|
330
|
+
else
|
331
|
+
raise "hash_to_lcons_args should take Hash argument (or Association Array argument)"
|
332
|
+
end
|
333
|
+
|
334
|
+
if(hash_like.size == 0)
|
301
335
|
lcons_args = r_lang_nil()
|
302
|
-
elsif(
|
303
|
-
tag =
|
304
|
-
val =
|
336
|
+
elsif(hash_like.size == 1)
|
337
|
+
tag = hash_like.first[0]
|
338
|
+
val = hash_like.first[1]
|
305
339
|
lcons_args = lcons_gen( val )
|
306
340
|
if( tag != "" )
|
307
341
|
set_tag_to_lcons( lcons_args, tag )
|
308
342
|
end
|
309
343
|
else
|
310
344
|
idx = 0
|
311
|
-
|
345
|
+
hash_like.reverse_each(){|arg|
|
312
346
|
tag = arg[0]
|
313
347
|
val = arg[1]
|
314
348
|
if(idx == 0 )
|
@@ -322,6 +356,36 @@ module RBridge
|
|
322
356
|
idx = idx + 1
|
323
357
|
}
|
324
358
|
end
|
359
|
+
return lcons_args
|
360
|
+
end
|
361
|
+
|
362
|
+
def self.create_ns_function_call( ns, fname, hash_like )
|
363
|
+
raise "create_ns_function_call should take String for namespace" if(ns.class != String)
|
364
|
+
raise "create_ns_function_call should take String for function name" if(fname.class != String)
|
365
|
+
raise "create_ns_function_call should take Hash like structure for function arguments" if(hash_like.class != Hash && hash_like.class != Array)
|
366
|
+
lcons_args = hash_to_lcons_args( hash_like )
|
367
|
+
|
368
|
+
new_function_call = r_lang_create_ns_fcall(ns, fname, lcons_args)
|
369
|
+
ptr_manager_add_ptr_to_current( new_function_call )
|
370
|
+
return new_function_call
|
371
|
+
end
|
372
|
+
|
373
|
+
def self.create_env_function_call( env, fname, hash_like )
|
374
|
+
raise "create_env_function_call should take String for env" if(env.class != String)
|
375
|
+
raise "create_env_function_call should take String for function name" if(fname.class != String)
|
376
|
+
raise "create_env_function_call should take Hash like structure for function arguments" if(hash_like.class != Hash && hash_like.class != Array)
|
377
|
+
lcons_args = hash_to_lcons_args( hash_like )
|
378
|
+
|
379
|
+
new_function_call = r_lang_create_env_fcall(env, fname, lcons_args)
|
380
|
+
ptr_manager_add_ptr_to_current( new_function_call )
|
381
|
+
return new_function_call
|
382
|
+
end
|
383
|
+
|
384
|
+
def self.create_function_call( fname, hash_like )
|
385
|
+
raise "create_function_call should take String for function name" if(fname.class != String)
|
386
|
+
raise "create_function_call should take Hash like structure for function arguments" if(hash_like.class != Hash && hash_like.class != Array)
|
387
|
+
lcons_args = hash_to_lcons_args( hash_like )
|
388
|
+
|
325
389
|
new_function_call = r_lang_create_fcall(fname, lcons_args)
|
326
390
|
ptr_manager_add_ptr_to_current( new_function_call )
|
327
391
|
return new_function_call
|
@@ -1,25 +1,48 @@
|
|
1
1
|
require "r_bridge/r_bridge_ffi"
|
2
2
|
|
3
3
|
module RBridge
|
4
|
-
def self.
|
4
|
+
def self.create_ns_lazy_function( ns, fname, hash_like , param_manager)
|
5
|
+
raise "create_ns_lazy_function should take String for namespace" if(ns.class != String)
|
6
|
+
raise "create_ns_lazy_function should take String for function name" if(fname.class != String)
|
7
|
+
raise "create_ns_lazy_function should take Hash like structure for function arguments" if(hash_like.class != Hash && hash_like.class != Array)
|
8
|
+
return LazyFunc.new( ns, nil, fname, hash_like, param_manager)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.create_env_lazy_function( env, fname, hash_like , param_manager)
|
12
|
+
raise "create_env_lazy_function should take String for environment" if(env.class != String)
|
13
|
+
raise "create_env_lazy_function should take String for function name" if(fname.class != String)
|
14
|
+
raise "create_env_lazy_function should take Hash like structure for function arguments" if(hash_like.class != Hash && hash_like.class != Array)
|
15
|
+
return LazyFunc.new( nil, env, fname, hash_like, param_manager)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create_lazy_function( fname, hash_like , param_manager)
|
5
19
|
raise "create_lazy_function should take String for function name" if(fname.class != String)
|
6
|
-
raise "create_lazy_function should take Hash for function arguments" if(
|
7
|
-
return LazyFunc.new(
|
20
|
+
raise "create_lazy_function should take Hash like structure for function arguments" if(hash_like.class != Hash && hash_like.class != Array)
|
21
|
+
return LazyFunc.new( nil, nil, fname, hash_like, param_manager)
|
8
22
|
end
|
9
23
|
|
10
|
-
def self.
|
11
|
-
|
24
|
+
def self.create_function_call_from_lazy_function_attrs( ns, env, fname, fargs, param_manager, result_manager)
|
25
|
+
|
26
|
+
new_arg_assoc_array = []
|
27
|
+
fargs.each(){|key, val|
|
28
|
+
|
29
|
+
if val.is_a? RResultPrevious
|
30
|
+
r_previous = result_manager.get_previous() # if r_nil (i.e. 1st instruction or no previous result-store instructions) we need to use default one.
|
31
|
+
if ! RBridge::is_r_nil?(r_previous) # When previous result exists
|
32
|
+
new_arg_assoc_array << [key, r_previous]
|
33
|
+
next
|
34
|
+
else # When previous result does not exist
|
35
|
+
val = val.default
|
36
|
+
end
|
37
|
+
end
|
12
38
|
|
13
|
-
new_arg_hash = {}
|
14
|
-
farg_keys.each(){|key|
|
15
|
-
val = fargs[key]
|
16
39
|
case val
|
17
40
|
when LazyFunc then
|
18
|
-
|
41
|
+
new_arg_assoc_array << [key, create_function_call_from_lazy_function_attrs( val.ns, val.env, val.fname, val.args , param_manager, result_manager )]
|
19
42
|
when RResultName , RResultNameArray then
|
20
|
-
|
43
|
+
new_arg_assoc_array << [key, result_manager.get_last_for( val )]
|
21
44
|
when RParamName then
|
22
|
-
|
45
|
+
new_arg_assoc_array << [key, param_manager.get_r_object( val )]
|
23
46
|
when RNameContainer then
|
24
47
|
idx = 0
|
25
48
|
while idx < val.elems.size do
|
@@ -27,51 +50,71 @@ module RBridge
|
|
27
50
|
case elem
|
28
51
|
when RResultName, RResultNameArray then
|
29
52
|
result = result_manager.get_last_for( elem )
|
30
|
-
if( ! result
|
31
|
-
|
53
|
+
if( ! RBridge::is_r_nil?(result) )
|
54
|
+
new_arg_assoc_array << [key, result]
|
32
55
|
break
|
33
56
|
end
|
34
57
|
when RParamName then
|
35
58
|
result = param_manager.get_r_object( elem )
|
36
|
-
if( ! result
|
37
|
-
|
59
|
+
if( ! RBridge::is_r_nil?(result) )
|
60
|
+
new_arg_assoc_array << [key, result]
|
38
61
|
break
|
39
62
|
end
|
40
63
|
else # R object
|
41
|
-
|
64
|
+
new_arg_assoc_array << [key, val]
|
42
65
|
break
|
43
66
|
end
|
44
67
|
idx = idx + 1
|
45
68
|
end
|
46
69
|
if(idx == val.elems.size ) # Not found
|
47
|
-
|
70
|
+
new_arg_assoc_array << [key, RBridge::r_nil()]
|
48
71
|
end
|
72
|
+
when RInstPrevious
|
73
|
+
new_arg_assoc_array << [key, result_manager.get_previous_inst_name() ]
|
49
74
|
else # R object
|
50
|
-
|
75
|
+
new_arg_assoc_array << [key, val]
|
51
76
|
end
|
52
77
|
}
|
53
|
-
|
78
|
+
if( ns.nil? )
|
79
|
+
if( env.nil? )
|
80
|
+
return create_function_call( fname, new_arg_assoc_array )
|
81
|
+
else
|
82
|
+
return create_env_function_call( env, fname, new_arg_assoc_array )
|
83
|
+
end
|
84
|
+
else
|
85
|
+
if( env.nil? )
|
86
|
+
return create_ns_function_call( ns, fname, new_arg_assoc_array )
|
87
|
+
else
|
88
|
+
raise "namespace and environment are not allowed to be specified at the same time."
|
89
|
+
end
|
90
|
+
end
|
54
91
|
end
|
55
92
|
|
56
93
|
def self.exec_lazy_function( lazy_func , result_manager , allow_nil_result: false )
|
57
94
|
raise "exec_lazy_function should take LazyFunc object" if(lazy_func.class != LazyFunc)
|
58
95
|
raise "exec_lazy_function should take RResultManager or Nil for 2nd argment: " + result_manager.class.to_s if(! [RResultManager, NilClass].include?(result_manager.class) )
|
96
|
+
ns = lazy_func.ns
|
97
|
+
env = lazy_func.env
|
59
98
|
fname = lazy_func.fname
|
60
99
|
arg_hash = lazy_func.args
|
61
100
|
param_manager = lazy_func.param_manager
|
62
101
|
|
63
|
-
func =
|
102
|
+
func = create_function_call_from_lazy_function_attrs(ns, env, fname, arg_hash, param_manager, result_manager)
|
64
103
|
result = exec_function( func , allow_nil_result: allow_nil_result )
|
65
104
|
return result
|
66
105
|
end
|
67
106
|
|
68
107
|
class LazyFunc
|
108
|
+
attr :ns
|
109
|
+
attr :env
|
69
110
|
attr :fname
|
70
111
|
attr :args
|
71
112
|
attr :param_manager
|
72
113
|
|
73
|
-
def initialize( fname, arg_hash, param_manager)
|
114
|
+
def initialize( ns, env, fname, arg_hash, param_manager)
|
74
115
|
raise "LazyFunc requires RParamManager object for param_manager argument " if ! param_manager.is_a?(RParamManager)
|
116
|
+
@ns = ns # When namespace does not need to be specified, set nil.
|
117
|
+
@env = env # When environment does not need to be specified, set nil.
|
75
118
|
@fname = fname
|
76
119
|
@args = arg_hash
|
77
120
|
@param_manager = param_manager
|
@@ -86,6 +129,7 @@ module RBridge
|
|
86
129
|
end
|
87
130
|
|
88
131
|
class RParamManager
|
132
|
+
attr :param_hash , true
|
89
133
|
def initialize(hash)
|
90
134
|
@param_hash = hash
|
91
135
|
end
|
@@ -112,6 +156,22 @@ module RBridge
|
|
112
156
|
end
|
113
157
|
end
|
114
158
|
|
159
|
+
class RResultPrevious
|
160
|
+
# RResultPrevious is used for result from the previous instruction.
|
161
|
+
# If the instruction is the 1st one, there are no previous ones. At this time, default one is used.
|
162
|
+
attr :default
|
163
|
+
def initialize(val)
|
164
|
+
if ! ( val.is_a?(RNameContainer) || val.is_a?(RResultName) || val.is_a?(RResultNameArray) || val.is_a?(RParamName) || ::RBridge.is_pointer?( val ) )
|
165
|
+
raise "RResultPrevious.new requires RNameContainer, RResultName, RResultNameArray, RParamName or R object as default"
|
166
|
+
end
|
167
|
+
@default = val
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
class RInstPrevious
|
172
|
+
# RInstPrevious is used to obtain the previous instruction name.
|
173
|
+
end
|
174
|
+
|
115
175
|
class RResultManager
|
116
176
|
def initialize
|
117
177
|
@results = []
|
@@ -125,7 +185,7 @@ module RBridge
|
|
125
185
|
@results << [inst_name, r_obj ]
|
126
186
|
end
|
127
187
|
|
128
|
-
def get_last_index_for( result_name )
|
188
|
+
def get_last_index_for( result_name ) # From this method, if result name is not found return (Ruby) nil.
|
129
189
|
name = result_name.name
|
130
190
|
|
131
191
|
idx = @results.size - 1
|
@@ -143,18 +203,18 @@ module RBridge
|
|
143
203
|
end
|
144
204
|
end
|
145
205
|
|
146
|
-
def get_last_for( r_result ) # If corresponding result name is not found, return
|
206
|
+
def get_last_for( r_result ) # If corresponding result name is not found, return r_nil().
|
147
207
|
raise "get_last_for method requires RResultName or RResultNameArray for its argument." if ! ( r_result.is_a?(RResultName) || r_result.is_a?(RResultNameArray) )
|
148
208
|
if( r_result.is_a? RResultName)
|
149
209
|
inst_name = r_result.name
|
150
210
|
|
151
211
|
elem_to_match = @results.reverse.find{|elem| elem[0] == inst_name }
|
152
212
|
if elem_to_match.nil?
|
153
|
-
return
|
213
|
+
return RBridge::r_nil()
|
154
214
|
else
|
155
215
|
r_obj = elem_to_match[1]
|
156
216
|
if RBridge::is_r_nil?( r_obj )
|
157
|
-
return
|
217
|
+
return RBridge::r_nil()
|
158
218
|
else
|
159
219
|
return r_obj
|
160
220
|
end
|
@@ -170,7 +230,7 @@ module RBridge
|
|
170
230
|
}
|
171
231
|
|
172
232
|
if( index_array.all?(nil) )
|
173
|
-
return
|
233
|
+
return RBridge::r_nil()
|
174
234
|
else
|
175
235
|
index_array.delete(nil)
|
176
236
|
if ! index_array.empty?
|
@@ -178,13 +238,32 @@ module RBridge
|
|
178
238
|
r_obj = @results[last_idx][1]
|
179
239
|
return r_obj
|
180
240
|
else
|
181
|
-
return
|
241
|
+
return RBridge::r_nil()
|
182
242
|
end
|
183
243
|
end
|
184
244
|
else
|
185
245
|
raise "get_last_for() takes unexpected object"
|
186
246
|
end
|
187
247
|
end
|
248
|
+
|
249
|
+
def get_previous()
|
250
|
+
if @results.size > 0
|
251
|
+
r_obj = @results.last[1]
|
252
|
+
return r_obj
|
253
|
+
else
|
254
|
+
return RBridge::r_nil()
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def get_previous_inst_name()
|
259
|
+
if @results.size > 0
|
260
|
+
last_inst_name = @results.last[0]
|
261
|
+
r_obj = RBridge::create_strvec([last_inst_name])
|
262
|
+
return r_obj
|
263
|
+
else
|
264
|
+
return RBridge::r_nil()
|
265
|
+
end
|
266
|
+
end
|
188
267
|
end
|
189
268
|
|
190
269
|
class RNameContainer
|
data/lib/r_bridge/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r_bridge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toshihiro Umehara
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -73,7 +73,7 @@ metadata:
|
|
73
73
|
homepage_uri: https://github.com/niceume/r_bridge
|
74
74
|
source_code_uri: https://github.com/niceume/r_bridge
|
75
75
|
changelog_uri: https://github.com/niceume/r_bridge
|
76
|
-
post_install_message:
|
76
|
+
post_install_message:
|
77
77
|
rdoc_options: []
|
78
78
|
require_paths:
|
79
79
|
- lib
|
@@ -88,8 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
requirements: []
|
91
|
-
rubygems_version: 3.
|
92
|
-
signing_key:
|
91
|
+
rubygems_version: 3.2.31
|
92
|
+
signing_key:
|
93
93
|
specification_version: 4
|
94
94
|
summary: Enables Ruby to construct and evaluate R internal objects
|
95
95
|
test_files: []
|