r_bridge 0.5.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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +6 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +674 -0
- data/README.md +365 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/r_bridge/extconf.rb +78 -0
- data/ext/r_bridge/r_bridge.c +5 -0
- data/ext/r_bridge/r_embed.c +26 -0
- data/ext/r_bridge/r_eval.c +29 -0
- data/ext/r_bridge/r_lang.c +62 -0
- data/ext/r_bridge/r_list.c +34 -0
- data/ext/r_bridge/r_mysum.c +89 -0
- data/ext/r_bridge/r_ptr.c +18 -0
- data/ext/r_bridge/r_vec.c +76 -0
- data/ext/r_bridge/win_compat.h +10 -0
- data/lib/r_bridge.rb +10 -0
- data/lib/r_bridge/r_bridge_ffi.rb +480 -0
- data/lib/r_bridge/r_bridge_lazyfunc_ext.rb +202 -0
- data/lib/r_bridge/version.rb +3 -0
- data/r_bridge.gemspec +32 -0
- metadata +91 -0
@@ -0,0 +1,202 @@
|
|
1
|
+
require "r_bridge/r_bridge_ffi"
|
2
|
+
|
3
|
+
module RBridge
|
4
|
+
def self.create_lazy_function( fname, hash , param_manager)
|
5
|
+
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(hash.class != Hash)
|
7
|
+
return LazyFunc.new( fname, hash , param_manager)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.create_function_call_from_lazy_function ( fname, fargs, param_manager, result_manager)
|
11
|
+
farg_keys = fargs.keys
|
12
|
+
|
13
|
+
new_arg_hash = {}
|
14
|
+
farg_keys.each(){|key|
|
15
|
+
val = fargs[key]
|
16
|
+
case val
|
17
|
+
when LazyFunc then
|
18
|
+
new_arg_hash[key] = create_function_call_from_lazy_function( val.fname, val.args , param_manager, result_manager )
|
19
|
+
when RResultName , RResultNameArray then
|
20
|
+
new_arg_hash[key] = result_manager.get_last_for( val )
|
21
|
+
when RParamName then
|
22
|
+
new_arg_hash[key] = param_manager.get_r_object( val )
|
23
|
+
when RNameContainer then
|
24
|
+
idx = 0
|
25
|
+
while idx < val.elems.size do
|
26
|
+
elem = val.elems[idx]
|
27
|
+
case elem
|
28
|
+
when RResultName, RResultNameArray then
|
29
|
+
result = result_manager.get_last_for( elem )
|
30
|
+
if( ! result.nil? )
|
31
|
+
new_arg_hash[key] = result
|
32
|
+
break
|
33
|
+
end
|
34
|
+
when RParamName then
|
35
|
+
result = param_manager.get_r_object( elem )
|
36
|
+
if( ! result.nil? )
|
37
|
+
new_arg_hash[key] = result
|
38
|
+
break
|
39
|
+
end
|
40
|
+
else # R object
|
41
|
+
new_arg_hash[key] = val
|
42
|
+
break
|
43
|
+
end
|
44
|
+
idx = idx + 1
|
45
|
+
end
|
46
|
+
if(idx == val.elems.size ) # Not found
|
47
|
+
new_arg_hash[key] = nil
|
48
|
+
end
|
49
|
+
else # R object
|
50
|
+
new_arg_hash[key] = val
|
51
|
+
end
|
52
|
+
}
|
53
|
+
return create_function_call( fname, new_arg_hash )
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.exec_lazy_function( lazy_func , result_manager , allow_nil_result: false )
|
57
|
+
raise "exec_lazy_function should take LazyFunc object" if(lazy_func.class != LazyFunc)
|
58
|
+
raise "exec_lazy_function should take RResultManager or Nil for 2nd argment: " + result_manager.class.to_s if(! [RResultManager, NilClass].include?(result_manager.class) )
|
59
|
+
fname = lazy_func.fname
|
60
|
+
arg_hash = lazy_func.args
|
61
|
+
param_manager = lazy_func.param_manager
|
62
|
+
|
63
|
+
func = create_function_call_from_lazy_function(fname, arg_hash, param_manager, result_manager)
|
64
|
+
result = exec_function( func , allow_nil_result: allow_nil_result )
|
65
|
+
return result
|
66
|
+
end
|
67
|
+
|
68
|
+
class LazyFunc
|
69
|
+
attr :fname
|
70
|
+
attr :args
|
71
|
+
attr :param_manager
|
72
|
+
|
73
|
+
def initialize( fname, arg_hash, param_manager)
|
74
|
+
raise "LazyFunc requires RParamManager object for param_manager argument " if ! param_manager.is_a?(RParamManager)
|
75
|
+
@fname = fname
|
76
|
+
@args = arg_hash
|
77
|
+
@param_manager = param_manager
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class RParamName
|
82
|
+
attr :name
|
83
|
+
def initialize(name)
|
84
|
+
@name = name
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class RParamManager
|
89
|
+
def initialize(hash)
|
90
|
+
@param_hash = hash
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_r_object(r_param)
|
94
|
+
raise "argument of get_r_object needs to be RParamName" if ! r_param.is_a?(RParamName)
|
95
|
+
stored_value = @param_hash[r_param.name]
|
96
|
+
return RBridge::convert_to_r_object(stored_value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class RResultName
|
101
|
+
attr :name
|
102
|
+
def initialize(name)
|
103
|
+
@name = name
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
class RResultNameArray
|
108
|
+
attr :elems
|
109
|
+
def initialize(ary)
|
110
|
+
raise if(! ary.all? {|i| i.is_a?(RResultName) })
|
111
|
+
@elems = ary
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class RResultManager
|
116
|
+
def initialize
|
117
|
+
@results = []
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_inst( inst_name )
|
121
|
+
@results << [inst_name, RBridge::r_lang_nil() ]
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_inst_r_obj( inst_name, r_obj )
|
125
|
+
@results << [inst_name, r_obj ]
|
126
|
+
end
|
127
|
+
|
128
|
+
def get_last_index_for( result_name )
|
129
|
+
name = result_name.name
|
130
|
+
|
131
|
+
idx = @results.size - 1
|
132
|
+
@results.reverse.each{|inst_name, r_obj|
|
133
|
+
if inst_name == name
|
134
|
+
break
|
135
|
+
else
|
136
|
+
idx = idx - 1
|
137
|
+
end
|
138
|
+
}
|
139
|
+
if idx < 0
|
140
|
+
return nil
|
141
|
+
else
|
142
|
+
return idx
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def get_last_for( r_result ) # If corresponding result name is not found, return nil.
|
147
|
+
raise "get_last_for method requires RResultName or RResultNameArray for its argument." if ! ( r_result.is_a?(RResultName) || r_result.is_a?(RResultNameArray) )
|
148
|
+
if( r_result.is_a? RResultName)
|
149
|
+
inst_name = r_result.name
|
150
|
+
|
151
|
+
elem_to_match = @results.reverse.find{|elem| elem[0] == inst_name }
|
152
|
+
if elem_to_match.nil?
|
153
|
+
return nil
|
154
|
+
else
|
155
|
+
r_obj = elem_to_match[1]
|
156
|
+
if RBridge::is_r_nil?( r_obj )
|
157
|
+
return nil
|
158
|
+
else
|
159
|
+
return r_obj
|
160
|
+
end
|
161
|
+
end
|
162
|
+
elsif( r_result.is_a? RResultNameArray)
|
163
|
+
index_array = r_result.elems.map(){|result_name|
|
164
|
+
if result_name.is_a? RResultName
|
165
|
+
get_last_index_for( result_name )
|
166
|
+
else
|
167
|
+
p result_name
|
168
|
+
raise "RResultNameArray should hold only RResultName objects"
|
169
|
+
end
|
170
|
+
}
|
171
|
+
|
172
|
+
if( index_array.all?(nil) )
|
173
|
+
return nil
|
174
|
+
else
|
175
|
+
index_array.delete(nil)
|
176
|
+
if ! index_array.empty?
|
177
|
+
last_idx = index_array.max
|
178
|
+
r_obj = @results[last_idx][1]
|
179
|
+
return r_obj
|
180
|
+
else
|
181
|
+
return nil
|
182
|
+
end
|
183
|
+
end
|
184
|
+
else
|
185
|
+
raise "get_last_for() takes unexpected object"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class RNameContainer
|
191
|
+
attr :elems
|
192
|
+
def initialize(ary)
|
193
|
+
raise "RNameContainer constructor requires Array" if ! ary.is_a?(Array)
|
194
|
+
if(! ary.all? {|i| i.is_a?(RResultName) || i.is_a?(RResultNameArray) || i.is_a?(RParamName) || ::RBridge.is_pointer?( i ) })
|
195
|
+
p ary
|
196
|
+
raise "RNameContainer's elemet needs to be RResultName, RResultNameArray, RParamName or R object"
|
197
|
+
end
|
198
|
+
@elems = ary
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
data/r_bridge.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'lib/r_bridge/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "r_bridge"
|
5
|
+
spec.version = RBridge::VERSION
|
6
|
+
spec.authors = ["Toshihiro Umehara"]
|
7
|
+
spec.email = ["toshi@niceume.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{Enables Ruby to access and construct R internal objects}
|
10
|
+
spec.description = %q{R (language) provides C interface. This package utilize the interface and allow Ruby to manipulate and evaluate R's internal S expressions }
|
11
|
+
spec.homepage = "https://github.com/niceume/r_bridge"
|
12
|
+
spec.license = "GPL-3.0"
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
|
+
|
15
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
16
|
+
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
19
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
25
|
+
end
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.extensions = %w[ext/r_bridge/extconf.rb]
|
31
|
+
spec.add_dependency "ffi" , '~> 1.13', '>= 1.13.0'
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: r_bridge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Toshihiro Umehara
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.13.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.13'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.13.0
|
33
|
+
description: 'R (language) provides C interface. This package utilize the interface
|
34
|
+
and allow Ruby to manipulate and evaluate R''s internal S expressions '
|
35
|
+
email:
|
36
|
+
- toshi@niceume.com
|
37
|
+
executables: []
|
38
|
+
extensions:
|
39
|
+
- ext/r_bridge/extconf.rb
|
40
|
+
extra_rdoc_files: []
|
41
|
+
files:
|
42
|
+
- ".gitignore"
|
43
|
+
- ".travis.yml"
|
44
|
+
- Gemfile
|
45
|
+
- LICENSE.txt
|
46
|
+
- README.md
|
47
|
+
- Rakefile
|
48
|
+
- bin/console
|
49
|
+
- bin/setup
|
50
|
+
- ext/r_bridge/extconf.rb
|
51
|
+
- ext/r_bridge/r_bridge.c
|
52
|
+
- ext/r_bridge/r_embed.c
|
53
|
+
- ext/r_bridge/r_eval.c
|
54
|
+
- ext/r_bridge/r_lang.c
|
55
|
+
- ext/r_bridge/r_list.c
|
56
|
+
- ext/r_bridge/r_mysum.c
|
57
|
+
- ext/r_bridge/r_ptr.c
|
58
|
+
- ext/r_bridge/r_vec.c
|
59
|
+
- ext/r_bridge/win_compat.h
|
60
|
+
- lib/r_bridge.rb
|
61
|
+
- lib/r_bridge/r_bridge_ffi.rb
|
62
|
+
- lib/r_bridge/r_bridge_lazyfunc_ext.rb
|
63
|
+
- lib/r_bridge/version.rb
|
64
|
+
- r_bridge.gemspec
|
65
|
+
homepage: https://github.com/niceume/r_bridge
|
66
|
+
licenses:
|
67
|
+
- GPL-3.0
|
68
|
+
metadata:
|
69
|
+
homepage_uri: https://github.com/niceume/r_bridge
|
70
|
+
source_code_uri: https://github.com/niceume/r_bridge
|
71
|
+
changelog_uri: https://github.com/niceume/r_bridge
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 2.3.0
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubygems_version: 3.1.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Enables Ruby to access and construct R internal objects
|
91
|
+
test_files: []
|