rggen-core 0.24.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/rggen/core/base/component.rb +5 -6
- data/lib/rggen/core/base/component_factory.rb +9 -6
- data/lib/rggen/core/builder/builder.rb +6 -8
- data/lib/rggen/core/builder/component_registry.rb +1 -1
- data/lib/rggen/core/builder/feature_registry.rb +11 -8
- data/lib/rggen/core/builder/list_feature_entry.rb +5 -9
- data/lib/rggen/core/builder/loader_registry.rb +1 -2
- data/lib/rggen/core/builder/plugin_manager.rb +71 -31
- data/lib/rggen/core/builder/simple_feature_entry.rb +4 -4
- data/lib/rggen/core/core_extensions/object.rb +4 -4
- data/lib/rggen/core/facets.rb +2 -0
- data/lib/rggen/core/input_base/component.rb +12 -0
- data/lib/rggen/core/input_base/component_factory.rb +1 -0
- data/lib/rggen/core/input_base/feature.rb +20 -6
- data/lib/rggen/core/input_base/input_data.rb +17 -16
- data/lib/rggen/core/input_base/input_matcher.rb +5 -5
- data/lib/rggen/core/input_base/loader.rb +18 -20
- data/lib/rggen/core/input_base/property.rb +17 -11
- data/lib/rggen/core/input_base/yaml_loader.rb +6 -36
- data/lib/rggen/core/options.rb +2 -2
- data/lib/rggen/core/output_base/code_generator.rb +4 -5
- data/lib/rggen/core/output_base/document_component_factory.rb +10 -0
- data/lib/rggen/core/output_base/feature.rb +15 -11
- data/lib/rggen/core/output_base/file_writer.rb +2 -2
- data/lib/rggen/core/output_base/source_file_component_factory.rb +15 -0
- data/lib/rggen/core/output_base/template_engine.rb +4 -5
- data/lib/rggen/core/register_map/hash_loader.rb +11 -13
- data/lib/rggen/core/utility/code_utility/code_block.rb +11 -5
- data/lib/rggen/core/version.rb +1 -1
- data/lib/rggen/core.rb +2 -1
- metadata +8 -6
- data/lib/rggen/core/base/proxy_call.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe3a65999b49b800216dea110ca47e81c71cf4fe0a65626f50526be374647713
|
4
|
+
data.tar.gz: 160dbda800f4fef46bbe18ef34810851082d09271eb7754b6b4508eb4f56c8fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eae55af6cdaa6eff67f15ef508dcd32af950d72f18621d0b8769011957c9c6a72c9f3c41557d197a0c1e9fec25ecaff34364f3518cd04c12f22bdb6ee8efa6af
|
7
|
+
data.tar.gz: 3d030a72ade1067dbb7450ff30ef4cffc3d97430e73a4ea96f9fb310a5cb633e314f1a9b280d4c4e615b1fce2ace5f5456f2881bd76a18fa05cef60420989ada
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -44,7 +44,7 @@ Feedbacks, bug reports, questions and etc. are wellcome! You can post them by us
|
|
44
44
|
|
45
45
|
## Copyright & License
|
46
46
|
|
47
|
-
Copyright © 2017-
|
47
|
+
Copyright © 2017-2022 Taichi Ishitani. RgGen::Core is licensed under the [MIT License](https://opensource.org/licenses/MIT), see [LICENSE](LICENSE) for futher details.
|
48
48
|
|
49
49
|
## Code of Conduct
|
50
50
|
|
@@ -70,15 +70,14 @@ module RgGen
|
|
70
70
|
|
71
71
|
def define_proxy_calls(receiver, methods)
|
72
72
|
Array(methods)
|
73
|
-
.map(&:to_sym)
|
74
73
|
.each { |method| define_proxy_call(receiver, method) }
|
75
74
|
end
|
76
75
|
|
77
|
-
def define_proxy_call(receiver,
|
78
|
-
@
|
79
|
-
|
80
|
-
|
81
|
-
@
|
76
|
+
def define_proxy_call(receiver, method_name)
|
77
|
+
(@proxy_receivers ||= {})[method_name.to_sym] = receiver
|
78
|
+
define_singleton_method(method_name) do |*args, &block|
|
79
|
+
name = __method__
|
80
|
+
@proxy_receivers[name].__send__(name, *args, &block)
|
82
81
|
end
|
83
82
|
end
|
84
83
|
end
|
@@ -27,7 +27,7 @@ module RgGen
|
|
27
27
|
if root_factory?
|
28
28
|
[nil, preprocess(args)]
|
29
29
|
else
|
30
|
-
[args.first, preprocess(args[1
|
30
|
+
[args.first, preprocess(args[1..])]
|
31
31
|
end
|
32
32
|
create_component(parent, sources) do |component|
|
33
33
|
build_component(parent, component, sources)
|
@@ -43,11 +43,15 @@ module RgGen
|
|
43
43
|
|
44
44
|
def create_component(parent, sources, &block)
|
45
45
|
actual_sources = Array(select_actual_sources(*sources))
|
46
|
-
|
47
|
-
.new(parent, component_name, layer, *actual_sources, &block)
|
46
|
+
create_component?(*actual_sources) &&
|
47
|
+
@target_component.new(parent, component_name, layer, *actual_sources, &block)
|
48
48
|
end
|
49
49
|
|
50
|
-
def select_actual_sources(*
|
50
|
+
def select_actual_sources(*_sources)
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_component?(*_sources)
|
54
|
+
true
|
51
55
|
end
|
52
56
|
|
53
57
|
def build_component(parent, component, sources)
|
@@ -88,8 +92,7 @@ module RgGen
|
|
88
92
|
end
|
89
93
|
|
90
94
|
def create_child(component, *args)
|
91
|
-
|
92
|
-
factory.create(component, *args)
|
95
|
+
find_child_factory(*args).create(component, *args)
|
93
96
|
end
|
94
97
|
end
|
95
98
|
end
|
@@ -43,9 +43,8 @@ module RgGen
|
|
43
43
|
else
|
44
44
|
@layers.values
|
45
45
|
end
|
46
|
-
target_layers
|
47
|
-
layer.add_feature_registry(name, registry)
|
48
|
-
end
|
46
|
+
target_layers
|
47
|
+
.each { |layer| layer.add_feature_registry(name, registry) }
|
49
48
|
end
|
50
49
|
|
51
50
|
[
|
@@ -79,8 +78,7 @@ module RgGen
|
|
79
78
|
if targets.empty?
|
80
79
|
@component_registries[type]
|
81
80
|
else
|
82
|
-
@component_registries[type]
|
83
|
-
.select { |name, _| targets.include?(name) }
|
81
|
+
@component_registries[type].slice(*targets)
|
84
82
|
end
|
85
83
|
registries.each_value.map(&:build_factory)
|
86
84
|
end
|
@@ -130,9 +128,9 @@ module RgGen
|
|
130
128
|
|
131
129
|
def component_registry(type, name, &body)
|
132
130
|
registries = @component_registries[type]
|
133
|
-
|
134
|
-
|
135
|
-
|
131
|
+
registries.key?(name) ||
|
132
|
+
(registries[name] = COMPONENT_REGISTRIES[type].new(name, self))
|
133
|
+
body && Docile.dsl_eval(registries[name], &body) || registries[name]
|
136
134
|
end
|
137
135
|
end
|
138
136
|
end
|
@@ -12,11 +12,11 @@ module RgGen
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def define_simple_feature(name, context = nil, &body)
|
15
|
-
create_new_entry(:simple, name, context, body)
|
15
|
+
create_new_entry(:simple, name, context, &body)
|
16
16
|
end
|
17
17
|
|
18
18
|
def define_list_feature(list_name, context = nil, &body)
|
19
|
-
create_new_entry(:list, list_name, context, body)
|
19
|
+
create_new_entry(:list, list_name, context, &body)
|
20
20
|
end
|
21
21
|
|
22
22
|
def define_list_item_feature(list_name, feature_name, context = nil, &body)
|
@@ -88,10 +88,9 @@ module RgGen
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def build_factories
|
91
|
-
@
|
92
|
-
.
|
93
|
-
.
|
94
|
-
.to_h
|
91
|
+
@feature_entries
|
92
|
+
.slice(*@enabled_features.keys)
|
93
|
+
.transform_values(&method(:build_factory))
|
95
94
|
end
|
96
95
|
|
97
96
|
private
|
@@ -100,9 +99,9 @@ module RgGen
|
|
100
99
|
simple: SimpleFeatureEntry, list: ListFeatureEntry
|
101
100
|
}.freeze
|
102
101
|
|
103
|
-
def create_new_entry(type, name, context, body)
|
102
|
+
def create_new_entry(type, name, context, &body)
|
104
103
|
entry = FEATURE_ENTRIES[type].new(self, name)
|
105
|
-
entry.setup(@base_feature, @factory, context, body)
|
104
|
+
entry.setup(@base_feature, @factory, context, &body)
|
106
105
|
@feature_entries[name] = entry
|
107
106
|
end
|
108
107
|
|
@@ -117,6 +116,10 @@ module RgGen
|
|
117
116
|
.feature?(feature_name)
|
118
117
|
@enabled_features[list_name].include?(feature_name)
|
119
118
|
end
|
119
|
+
|
120
|
+
def build_factory(entry)
|
121
|
+
entry.build_factory(@enabled_features[entry.name])
|
122
|
+
end
|
120
123
|
end
|
121
124
|
end
|
122
125
|
end
|
@@ -15,11 +15,11 @@ module RgGen
|
|
15
15
|
attr_reader :registry
|
16
16
|
attr_reader :name
|
17
17
|
|
18
|
-
def setup(base_feature, base_factory, context, body)
|
18
|
+
def setup(base_feature, base_factory, context, &body)
|
19
19
|
@base_feature = Class.new(base_feature)
|
20
20
|
@factory = Class.new(base_factory)
|
21
21
|
context && attach_shared_context(context)
|
22
|
-
|
22
|
+
block_given? && Docile.dsl_eval(self, @name, &body)
|
23
23
|
end
|
24
24
|
|
25
25
|
def match_entry_type?(entry_type)
|
@@ -49,9 +49,8 @@ module RgGen
|
|
49
49
|
@features[feature_name] ||= Class.new(@base_feature)
|
50
50
|
feature = @features[feature_name]
|
51
51
|
if context
|
52
|
-
feature.method_defined?(:shared_context) &&
|
53
|
-
raise BuilderError.new('shared context has already been set')
|
54
|
-
)
|
52
|
+
feature.method_defined?(:shared_context) &&
|
53
|
+
(raise BuilderError.new('shared context has already been set'))
|
55
54
|
feature.attach_context(context)
|
56
55
|
end
|
57
56
|
body && feature.class_exec(feature_name, &body)
|
@@ -87,10 +86,7 @@ module RgGen
|
|
87
86
|
end
|
88
87
|
|
89
88
|
def target_features(enabled_features)
|
90
|
-
enabled_features
|
91
|
-
.select { |n| @features.key?(n) }
|
92
|
-
.map { |n| [n, @features[n]] }
|
93
|
-
.to_h
|
89
|
+
@features.slice(*enabled_features)
|
94
90
|
end
|
95
91
|
end
|
96
92
|
end
|
@@ -22,26 +22,80 @@ module RgGen
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
class PluginInfo
|
26
|
+
attr_reader :name
|
27
|
+
attr_reader :setup_path
|
28
|
+
attr_reader :gem_name
|
29
|
+
attr_reader :version
|
30
|
+
|
31
|
+
def parse(setup_path_or_name, version)
|
32
|
+
setup_path_or_name = setup_path_or_name.to_s.strip
|
33
|
+
@name, @setup_path, @gem_name, @version =
|
34
|
+
if setup_file_directly_given?(setup_path_or_name)
|
35
|
+
[nil, setup_path_or_name, *find_plugin_gem(setup_path_or_name)]
|
36
|
+
else
|
37
|
+
[
|
38
|
+
setup_path_or_name, get_setup_path(setup_path_or_name),
|
39
|
+
extract_gem_name(setup_path_or_name), version
|
40
|
+
]
|
41
|
+
end
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
if name && version
|
47
|
+
"#{name} (#{version})"
|
48
|
+
elsif name
|
49
|
+
name
|
50
|
+
else
|
51
|
+
setup_path
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def setup_file_directly_given?(setup_path_or_name)
|
58
|
+
File.ext(setup_path_or_name) == 'rb' ||
|
59
|
+
File.basename(setup_path_or_name, '.*') == 'setup'
|
60
|
+
end
|
61
|
+
|
62
|
+
def find_plugin_gem(setup_path)
|
63
|
+
gemspec =
|
64
|
+
Gem::Specification
|
65
|
+
.each.find { |spec| match_gemspec?(spec, setup_path) }
|
66
|
+
gemspec && [gemspec.name, gemspec.version]
|
67
|
+
end
|
68
|
+
|
69
|
+
def match_gemspec?(gemspec, setup_path)
|
70
|
+
gemspec.full_require_paths.any?(&setup_path.method(:start_with?))
|
71
|
+
end
|
72
|
+
|
73
|
+
def extract_gem_name(plugin_name)
|
74
|
+
plugin_name.split('/', 2).first
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_setup_path(plugin_name)
|
78
|
+
base, sub_directory = plugin_name.split('/', 2)
|
79
|
+
base = base.sub(/^rggen[-_]/, '').tr('-', '_')
|
80
|
+
File.join(*['rggen', base, sub_directory, 'setup'].compact)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
25
84
|
class PluginManager
|
26
85
|
def initialize(builder)
|
27
86
|
@builder = builder
|
28
87
|
@plugins = []
|
29
88
|
end
|
30
89
|
|
31
|
-
def load_plugin(setup_path_or_name)
|
32
|
-
|
33
|
-
|
34
|
-
if setup_file_directly_given?(setup_path_or_name)
|
35
|
-
setup_path_or_name
|
36
|
-
else
|
37
|
-
get_setup_path(setup_path_or_name)
|
38
|
-
end
|
39
|
-
read_setup_file(setup_path, setup_path_or_name)
|
90
|
+
def load_plugin(setup_path_or_name, version = nil)
|
91
|
+
info = PluginInfo.new.parse(setup_path_or_name, version)
|
92
|
+
read_setup_file(info)
|
40
93
|
end
|
41
94
|
|
42
95
|
def load_plugins(plugins, no_default_plugins, activation = true)
|
43
96
|
RgGen.builder(@builder)
|
44
|
-
merge_plugins(plugins, no_default_plugins)
|
97
|
+
merge_plugins(plugins, no_default_plugins)
|
98
|
+
.each { |plugin| load_plugin(*plugin) }
|
45
99
|
activation && activate_plugins
|
46
100
|
end
|
47
101
|
|
@@ -64,27 +118,11 @@ module RgGen
|
|
64
118
|
|
65
119
|
private
|
66
120
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
def get_setup_path(name)
|
73
|
-
base, sub_directory = name.split('/', 2)
|
74
|
-
base = base.sub(/^rggen[-_]/, '').tr('-', '_')
|
75
|
-
File.join(*['rggen', base, sub_directory, 'setup'].compact)
|
76
|
-
end
|
77
|
-
|
78
|
-
def read_setup_file(setup_path, setup_path_or_name)
|
79
|
-
require setup_path
|
121
|
+
def read_setup_file(info)
|
122
|
+
info.gem_name && gem(info.gem_name, info.version)
|
123
|
+
require info.setup_path
|
80
124
|
rescue ::LoadError
|
81
|
-
|
82
|
-
if setup_path_or_name == setup_path
|
83
|
-
"cannot load such plugin: #{setup_path_or_name}"
|
84
|
-
else
|
85
|
-
"cannot load such plugin: #{setup_path_or_name} (#{setup_path})"
|
86
|
-
end
|
87
|
-
raise Core::PluginError.new(message)
|
125
|
+
raise Core::PluginError.new("cannot load such plugin: #{info}")
|
88
126
|
end
|
89
127
|
|
90
128
|
def merge_plugins(plugins, no_default_plugins)
|
@@ -110,7 +148,9 @@ module RgGen
|
|
110
148
|
|
111
149
|
def plugins_from_env
|
112
150
|
ENV['RGGEN_PLUGINS']
|
113
|
-
&.split(':')
|
151
|
+
&.split(':')
|
152
|
+
&.reject(&:blank?)
|
153
|
+
&.map { |entry| entry.split(',', 2) }
|
114
154
|
end
|
115
155
|
|
116
156
|
def plugin?(plugin_module)
|
@@ -12,8 +12,8 @@ module RgGen
|
|
12
12
|
attr_reader :registry
|
13
13
|
attr_reader :name
|
14
14
|
|
15
|
-
def setup(base_feature, factory, context, body)
|
16
|
-
@feature = define_feature(base_feature, context, body)
|
15
|
+
def setup(base_feature, factory, context, &body)
|
16
|
+
@feature = define_feature(base_feature, context, &body)
|
17
17
|
@factory = factory
|
18
18
|
end
|
19
19
|
|
@@ -27,10 +27,10 @@ module RgGen
|
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
def define_feature(base, context, body)
|
30
|
+
def define_feature(base, context, &body)
|
31
31
|
feature = Class.new(base)
|
32
32
|
context && feature.attach_context(context)
|
33
|
-
|
33
|
+
block_given? && feature.class_exec(@name, &body)
|
34
34
|
feature
|
35
35
|
end
|
36
36
|
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
class Object
|
4
4
|
def export_instance_variable(variable, to)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
instance_variable_defined?(variable) &&
|
6
|
+
instance_variable_get(variable)
|
7
|
+
.yield_self { |v| block_given? ? yield(v) : v }
|
8
|
+
.yield_self { |v| to.instance_variable_set(variable, v) }
|
9
9
|
end
|
10
10
|
|
11
11
|
def singleton_exec(*args, &block)
|
data/lib/rggen/core/facets.rb
CHANGED
@@ -9,10 +9,22 @@ module RgGen
|
|
9
9
|
define_proxy_calls(feature, feature.properties)
|
10
10
|
end
|
11
11
|
|
12
|
+
def document_only
|
13
|
+
@document_only = true
|
14
|
+
end
|
15
|
+
|
16
|
+
def document_only?
|
17
|
+
instance_variable_defined?(:@document_only) && @document_only
|
18
|
+
end
|
19
|
+
|
12
20
|
def properties
|
13
21
|
features.flat_map(&:properties)
|
14
22
|
end
|
15
23
|
|
24
|
+
def post_build
|
25
|
+
features.each(&:post_build)
|
26
|
+
end
|
27
|
+
|
16
28
|
def verify(scope)
|
17
29
|
features.each { |feature| feature.verify(scope) }
|
18
30
|
children.each { |child| child.verify(scope) } if scope == :all
|
@@ -34,6 +34,13 @@ module RgGen
|
|
34
34
|
|
35
35
|
attr_reader :builders
|
36
36
|
|
37
|
+
def post_build(&block)
|
38
|
+
@post_builders ||= []
|
39
|
+
@post_builders << block
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :post_builders
|
43
|
+
|
37
44
|
def active_feature?
|
38
45
|
!passive_feature?
|
39
46
|
end
|
@@ -68,6 +75,7 @@ module RgGen
|
|
68
75
|
export_instance_variable(:@properties, subclass, &:dup)
|
69
76
|
export_instance_variable(:@ignore_empty_value, subclass)
|
70
77
|
export_instance_variable(:@builders, subclass, &:dup)
|
78
|
+
export_instance_variable(:@post_builders, subclass, &:dup)
|
71
79
|
export_instance_variable(:@input_matcher, subclass)
|
72
80
|
export_instance_variable(:@printables, subclass, &:dup)
|
73
81
|
export_verifiers(subclass) if @verifiers
|
@@ -95,6 +103,12 @@ module RgGen
|
|
95
103
|
self.class.builders && do_build(args)
|
96
104
|
end
|
97
105
|
|
106
|
+
def post_build
|
107
|
+
self.class.post_builders&.each do |post_builder|
|
108
|
+
instance_exec(&post_builder)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
98
112
|
def verify(scope)
|
99
113
|
verified?(scope) || do_verify(scope)
|
100
114
|
end
|
@@ -102,7 +116,7 @@ module RgGen
|
|
102
116
|
def printables
|
103
117
|
helper
|
104
118
|
.printables
|
105
|
-
&.map { |name, body| [name, printable(name, body)] }
|
119
|
+
&.map { |name, body| [name, printable(name, &body)] }
|
106
120
|
end
|
107
121
|
|
108
122
|
def printable?
|
@@ -119,10 +133,10 @@ module RgGen
|
|
119
133
|
|
120
134
|
def do_build(args)
|
121
135
|
@position = args.last.position
|
122
|
-
|
123
|
-
match_automatically? && match_pattern(
|
136
|
+
value = args.last.value
|
137
|
+
match_automatically? && match_pattern(value)
|
124
138
|
Array(self.class.builders)
|
125
|
-
.each { |builder| instance_exec(*args, &builder) }
|
139
|
+
.each { |builder| instance_exec(*args[0..-2], value, &builder) }
|
126
140
|
end
|
127
141
|
|
128
142
|
attr_reader :position
|
@@ -154,8 +168,8 @@ module RgGen
|
|
154
168
|
(@verified ||= {})[scope] = true
|
155
169
|
end
|
156
170
|
|
157
|
-
def printable(name, body)
|
158
|
-
|
171
|
+
def printable(name, &body)
|
172
|
+
block_given? ? instance_exec(&body) : __send__(name)
|
159
173
|
end
|
160
174
|
end
|
161
175
|
end
|
@@ -17,14 +17,8 @@ module RgGen
|
|
17
17
|
|
18
18
|
def value(value_name, value, position = nil)
|
19
19
|
symbolized_name = value_name.to_sym
|
20
|
-
|
21
|
-
|
22
|
-
case value
|
23
|
-
when InputValue
|
24
|
-
value
|
25
|
-
else
|
26
|
-
InputValue.new(value, position)
|
27
|
-
end
|
20
|
+
valid_value?(symbolized_name) &&
|
21
|
+
assign_value(symbolized_name, value, position)
|
28
22
|
end
|
29
23
|
|
30
24
|
def []=(value_name, position_or_value, value = nil)
|
@@ -44,16 +38,14 @@ module RgGen
|
|
44
38
|
|
45
39
|
def child(layer, value_list = nil, &block)
|
46
40
|
create_child_data(layer) do |child_data|
|
47
|
-
child_data.build_by_block(block)
|
41
|
+
child_data.build_by_block(&block)
|
48
42
|
child_data.values(value_list)
|
49
43
|
@children << child_data
|
50
44
|
end
|
51
45
|
end
|
52
46
|
|
53
47
|
def load_file(file)
|
54
|
-
build_by_block
|
55
|
-
-> { #{File.binread(file)} } # -> { File.binread(file) }
|
56
|
-
BODY
|
48
|
+
build_by_block { instance_eval(File.binread(file), file, 1) }
|
57
49
|
end
|
58
50
|
|
59
51
|
private
|
@@ -62,6 +54,16 @@ module RgGen
|
|
62
54
|
@valid_value_lists[layer].include?(value_name)
|
63
55
|
end
|
64
56
|
|
57
|
+
def assign_value(value_name, value, position)
|
58
|
+
@values[value_name] =
|
59
|
+
case value
|
60
|
+
when InputValue
|
61
|
+
value
|
62
|
+
else
|
63
|
+
InputValue.new(value, position)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
65
67
|
def define_setter_methods
|
66
68
|
@valid_value_lists[layer].each(&method(:define_setter_method))
|
67
69
|
end
|
@@ -73,8 +75,7 @@ module RgGen
|
|
73
75
|
end
|
74
76
|
|
75
77
|
def value_setter(value_name, value, position)
|
76
|
-
position
|
77
|
-
value(value_name, value, position)
|
78
|
+
value(value_name, value, position || position_from_caller)
|
78
79
|
end
|
79
80
|
|
80
81
|
def position_from_caller
|
@@ -96,8 +97,8 @@ module RgGen
|
|
96
97
|
|
97
98
|
protected
|
98
99
|
|
99
|
-
def build_by_block(block)
|
100
|
-
|
100
|
+
def build_by_block(&block)
|
101
|
+
block_given? && Docile.dsl_eval(self, &block)
|
101
102
|
end
|
102
103
|
end
|
103
104
|
end
|
@@ -11,9 +11,10 @@ module RgGen
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def match(rhs)
|
14
|
-
rhs
|
15
|
-
|
16
|
-
|
14
|
+
rhs
|
15
|
+
.to_s
|
16
|
+
.yield_self { |s| ignore_blanks? && delete_blanks(s) || s }
|
17
|
+
.yield_self(&method(:match_patterns))
|
17
18
|
end
|
18
19
|
|
19
20
|
def match_automatically?
|
@@ -64,8 +65,7 @@ module RgGen
|
|
64
65
|
index, match_data =
|
65
66
|
@patterns
|
66
67
|
.transform_values { |pattern| pattern.match(rhs) }
|
67
|
-
.
|
68
|
-
.max_by { |_, m| m[0].length }
|
68
|
+
.max_by { |_, m| m && m[0].length || 0 }
|
69
69
|
match_data && [convert_match_data(match_data), index]
|
70
70
|
end
|
71
71
|
|
@@ -42,44 +42,42 @@ module RgGen
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def format_sub_layer(read_data, input_data, layer, file)
|
45
|
-
format_sub_layer_data(read_data, layer, file)
|
46
|
-
|
47
|
-
|
48
|
-
format(data, input_data.child(sub_layer), sub_layer, file)
|
49
|
-
end
|
45
|
+
format_sub_layer_data(read_data, layer, file)&.each do |(sub_layer, data)|
|
46
|
+
format(data, input_data.child(sub_layer), sub_layer, file)
|
47
|
+
end
|
50
48
|
end
|
51
49
|
|
52
50
|
def format_layer_data(_read_data, _layer, _file)
|
53
51
|
end
|
54
52
|
|
55
53
|
def format_layer_data_by_extractors(read_data, layer)
|
56
|
-
layer_data =
|
57
|
-
|
58
|
-
|
59
|
-
.
|
60
|
-
.each do |extractor|
|
61
|
-
extract_value(read_data, extractor, layer_data, value)
|
62
|
-
end
|
63
|
-
end
|
54
|
+
layer_data =
|
55
|
+
valid_values(layer)
|
56
|
+
.map { |value_name| extract_value(read_data, layer, value_name) }
|
57
|
+
.compact.to_h
|
64
58
|
layer_data.empty? ? nil : layer_data
|
65
59
|
end
|
66
60
|
|
67
|
-
def extract_value(read_data,
|
68
|
-
|
69
|
-
|
61
|
+
def extract_value(read_data, layer, value_name)
|
62
|
+
value =
|
63
|
+
@extractors
|
64
|
+
.select { |extractor| extractor.target_value?(layer, value_name) }
|
65
|
+
.map { |extractor| extractor.extract(read_data) }
|
66
|
+
.compact.last
|
67
|
+
value && [value_name, value]
|
70
68
|
end
|
71
69
|
|
72
70
|
def filter_layer_data(layer_data, layer)
|
73
|
-
layer_data
|
74
|
-
.select { |key, _| valid_values(layer).include?(key) }
|
71
|
+
layer_data.slice(*valid_values(layer))
|
75
72
|
end
|
76
73
|
|
77
74
|
def format_sub_layer_data(_read_data, _layer, _file)
|
78
75
|
end
|
79
76
|
|
80
77
|
def valid_values(layer)
|
81
|
-
@valid_value_lists[layer]
|
82
|
-
|
78
|
+
list = @valid_value_lists[layer]
|
79
|
+
ignore_values = @ignore_values[layer]
|
80
|
+
ignore_values && (list - ignore_values) || list
|
83
81
|
end
|
84
82
|
end
|
85
83
|
end
|
@@ -5,13 +5,18 @@ module RgGen
|
|
5
5
|
module InputBase
|
6
6
|
class Property
|
7
7
|
def self.define(feature, name, **options, &body)
|
8
|
-
new(name, options, body).define(feature)
|
8
|
+
new(name, options, &body).define(feature)
|
9
9
|
end
|
10
10
|
|
11
|
-
def initialize(name, options, body)
|
11
|
+
def initialize(name, options, &body)
|
12
12
|
@name = name
|
13
13
|
@options = options
|
14
|
-
@costom_property =
|
14
|
+
@costom_property =
|
15
|
+
if options[:body]
|
16
|
+
create_costom_property(&options[:body])
|
17
|
+
elsif block_given?
|
18
|
+
create_costom_property(&body)
|
19
|
+
end
|
15
20
|
end
|
16
21
|
|
17
22
|
attr_reader :name
|
@@ -19,15 +24,15 @@ module RgGen
|
|
19
24
|
def define(feature)
|
20
25
|
feature.class_exec(self) do |property|
|
21
26
|
define_method(property.name) do |*args, &block|
|
22
|
-
property.evaluate(self, args, block)
|
27
|
+
property.evaluate(self, args, &block)
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
27
|
-
def evaluate(feature, args, block)
|
32
|
+
def evaluate(feature, args, &block)
|
28
33
|
feature.verify(@options[:verify]) if @options.key?(:verify)
|
29
34
|
if proxy_property?
|
30
|
-
proxy_property(feature, args, block)
|
35
|
+
proxy_property(feature, args, &block)
|
31
36
|
else
|
32
37
|
default_property(feature)
|
33
38
|
end
|
@@ -35,7 +40,7 @@ module RgGen
|
|
35
40
|
|
36
41
|
private
|
37
42
|
|
38
|
-
def create_costom_property(body)
|
43
|
+
def create_costom_property(&body)
|
39
44
|
body && Module.new.module_eval do
|
40
45
|
define_method(:__costom_property__, &body)
|
41
46
|
instance_method(:__costom_property__)
|
@@ -50,7 +55,7 @@ module RgGen
|
|
50
55
|
].any?
|
51
56
|
end
|
52
57
|
|
53
|
-
def proxy_property(feature, args, block)
|
58
|
+
def proxy_property(feature, args, &block)
|
54
59
|
receiver, method =
|
55
60
|
if @costom_property
|
56
61
|
[@costom_property.bind(feature), :call]
|
@@ -63,7 +68,7 @@ module RgGen
|
|
63
68
|
end
|
64
69
|
|
65
70
|
def default_property(feature)
|
66
|
-
varible_name = "@#{@name
|
71
|
+
varible_name = "@#{@name.to_s.delete_suffix('?')}"
|
67
72
|
if feature.instance_variable_defined?(varible_name)
|
68
73
|
feature.instance_variable_get(varible_name)
|
69
74
|
elsif @options.key?(:initial)
|
@@ -74,8 +79,9 @@ module RgGen
|
|
74
79
|
end
|
75
80
|
|
76
81
|
def set_initial_value(feature, varible_name)
|
77
|
-
|
78
|
-
|
82
|
+
@options[:initial]
|
83
|
+
.yield_self { |v| evaluate_default_initial_value(feature, v) }
|
84
|
+
.yield_self { |v| feature.instance_variable_set(varible_name, v) }
|
79
85
|
end
|
80
86
|
|
81
87
|
def evaluate_default_initial_value(feature, value)
|
@@ -6,43 +6,13 @@ module RgGen
|
|
6
6
|
module YAMLLoader
|
7
7
|
private
|
8
8
|
|
9
|
-
if RUBY_VERSION >= '2.6.0'
|
10
|
-
def yaml_safe_load(yaml, file)
|
11
|
-
YAML.safe_load(
|
12
|
-
yaml,
|
13
|
-
permitted_classes: [Symbol], aliases: true, filename: file,
|
14
|
-
symbolize_names: true
|
15
|
-
)
|
16
|
-
end
|
17
|
-
elsif RUBY_VERSION >= '2.5.0'
|
18
|
-
def yaml_safe_load(yaml, file)
|
19
|
-
YAML.safe_load(yaml, [Symbol], [], true, file, symbolize_names: true)
|
20
|
-
end
|
21
|
-
else
|
22
|
-
def yaml_safe_load(yaml, file)
|
23
|
-
reuslt = YAML.safe_load(yaml, [Symbol], [], true, file)
|
24
|
-
symbolize_keys(reuslt)
|
25
|
-
end
|
26
|
-
|
27
|
-
def symbolize_keys(result)
|
28
|
-
case result
|
29
|
-
when Hash then symbolize_hash(result)
|
30
|
-
when Array then symbolize_array(result)
|
31
|
-
else result
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def symbolize_hash(result)
|
36
|
-
result.map { |key, value| [key.to_sym, symbolize_keys(value)] }.to_h
|
37
|
-
end
|
38
|
-
|
39
|
-
def symbolize_array(result)
|
40
|
-
result.map(&method(:symbolize_keys))
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
9
|
def load_yaml(file)
|
45
|
-
|
10
|
+
yaml = File.binread(file)
|
11
|
+
YAML.safe_load(
|
12
|
+
yaml,
|
13
|
+
permitted_classes: [Symbol], aliases: true,
|
14
|
+
filename: file, symbolize_names: true
|
15
|
+
)
|
46
16
|
end
|
47
17
|
end
|
48
18
|
end
|
data/lib/rggen/core/options.rb
CHANGED
@@ -109,9 +109,9 @@ module RgGen
|
|
109
109
|
end
|
110
110
|
|
111
111
|
Options.add_option(:plugins) do |option|
|
112
|
-
option.long_option '--plugin PLUGIN'
|
112
|
+
option.long_option '--plugin PLUGIN[:VERSION]'
|
113
113
|
option.default { [] }
|
114
|
-
option.action { |value, options| options[:plugins] << value }
|
114
|
+
option.action { |value, options| options[:plugins] << value.split(':', 2) }
|
115
115
|
option.description 'Load a RgGen plugin ' \
|
116
116
|
"(name of plugin/path to 'setup.rb' file)"
|
117
117
|
end
|
@@ -4,14 +4,13 @@ module RgGen
|
|
4
4
|
module Core
|
5
5
|
module OutputBase
|
6
6
|
class CodeGenerator
|
7
|
-
def register(kind, block)
|
8
|
-
|
9
|
-
code_blocks[kind] << block
|
7
|
+
def register(kind, &block)
|
8
|
+
block_given? && (code_blocks[kind] << block)
|
10
9
|
end
|
11
10
|
|
12
11
|
def generate(context, code, kind)
|
13
12
|
code_blocks[kind].each do |block|
|
14
|
-
execute_code_block(context, code, block)
|
13
|
+
execute_code_block(context, code, &block)
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
@@ -27,7 +26,7 @@ module RgGen
|
|
27
26
|
@code_blocks ||= Hash.new { |blocks, kind| blocks[kind] = [] }
|
28
27
|
end
|
29
28
|
|
30
|
-
def execute_code_block(context, code, block)
|
29
|
+
def execute_code_block(context, code, &block)
|
31
30
|
if block.arity.zero?
|
32
31
|
code << context.instance_exec(&block)
|
33
32
|
else
|
@@ -40,26 +40,30 @@ module RgGen
|
|
40
40
|
|
41
41
|
[:pre_code, :main_code, :post_code].each do |phase|
|
42
42
|
define_method(phase) do |kind, **options, &body|
|
43
|
-
|
44
|
-
if options[:from_template]
|
45
|
-
caller_location = caller_locations(1, 1).first
|
46
|
-
template_path = extract_template_path(options)
|
47
|
-
-> { process_template(template_path, caller_location) }
|
48
|
-
else
|
49
|
-
body
|
50
|
-
end
|
51
|
-
code_generators[__method__] ||= CodeGenerator.new
|
52
|
-
code_generators[__method__].register(kind, block)
|
43
|
+
register_code_generator(__method__, kind, **options, &body)
|
53
44
|
end
|
54
45
|
end
|
55
46
|
|
47
|
+
def register_code_generator(phase, kind, **options, &body)
|
48
|
+
block =
|
49
|
+
if options[:from_template]
|
50
|
+
path = extract_template_path(options)
|
51
|
+
location = caller_locations(2, 1).first
|
52
|
+
-> { process_template(path, location) }
|
53
|
+
else
|
54
|
+
body
|
55
|
+
end
|
56
|
+
(code_generators[phase] ||= CodeGenerator.new)
|
57
|
+
.register(kind, &block)
|
58
|
+
end
|
59
|
+
|
56
60
|
def extract_template_path(options)
|
57
61
|
path = options[:from_template]
|
58
62
|
path.equal?(true) ? nil : path
|
59
63
|
end
|
60
64
|
|
61
65
|
def write_file(file_name_pattern, &body)
|
62
|
-
@file_writer = FileWriter.new(file_name_pattern, body)
|
66
|
+
@file_writer = FileWriter.new(file_name_pattern, &body)
|
63
67
|
end
|
64
68
|
|
65
69
|
def export(*methods)
|
@@ -4,7 +4,7 @@ module RgGen
|
|
4
4
|
module Core
|
5
5
|
module OutputBase
|
6
6
|
class FileWriter
|
7
|
-
def initialize(pattern, body)
|
7
|
+
def initialize(pattern, &body)
|
8
8
|
@pattern = Erubi::Engine.new(pattern)
|
9
9
|
@body = body
|
10
10
|
end
|
@@ -32,7 +32,7 @@ module RgGen
|
|
32
32
|
|
33
33
|
def create_directory(path)
|
34
34
|
directory = path.dirname
|
35
|
-
directory.directory? ||
|
35
|
+
directory.directory? || FileUtils.mkpath(directory)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module OutputBase
|
6
|
+
class SourceFileComponentFactory < ComponentFactory
|
7
|
+
private
|
8
|
+
|
9
|
+
def create_component?(_, register_map)
|
10
|
+
!register_map.document_only?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -11,15 +11,14 @@ module RgGen
|
|
11
11
|
caller_location ||= caller_locations(1, 1).first
|
12
12
|
path = File.ext(caller_location.path, file_extension.to_s)
|
13
13
|
end
|
14
|
-
render(context,
|
14
|
+
render(context, template(path))
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def
|
20
|
-
@templates ||=
|
21
|
-
|
22
|
-
end
|
19
|
+
def template(path)
|
20
|
+
@templates ||= {}
|
21
|
+
(@templates[path] ||= parse_template(path))
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
@@ -29,14 +29,13 @@ module RgGen
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def format_array_layer_data(read_data, layer, file)
|
32
|
-
read_data
|
33
|
-
|
34
|
-
|
32
|
+
read_data
|
33
|
+
.map { |data| fomrat_hash_layer_data(data, layer, file) }
|
34
|
+
.inject(&:merge)
|
35
35
|
end
|
36
36
|
|
37
37
|
def fomrat_hash_layer_data(read_data, layer, file)
|
38
|
-
convert_to_hash(read_data, file)
|
39
|
-
.reject { |key, _| SUB_LAYER_KEYS[layer]&.include?(key) }
|
38
|
+
convert_to_hash(read_data, file).except(*SUB_LAYER_KEYS[layer])
|
40
39
|
end
|
41
40
|
|
42
41
|
def format_sub_layer_data(read_data, layer, file)
|
@@ -48,25 +47,24 @@ module RgGen
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def format_array_sub_layer_data(read_data, layer, file)
|
51
|
-
read_data.each_with_object(
|
50
|
+
read_data.each_with_object([]) do |data, sub_layer_data|
|
52
51
|
format_hash_sub_layer_data(data, layer, file, sub_layer_data)
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
def format_hash_sub_layer_data(read_data, layer, file, sub_layer_data =
|
55
|
+
def format_hash_sub_layer_data(read_data, layer, file, sub_layer_data = [])
|
57
56
|
convert_to_hash(read_data, file)
|
58
|
-
.
|
59
|
-
.each
|
60
|
-
merge_sub_layer_data(sub_layer_data, layer, key, value)
|
61
|
-
end
|
57
|
+
.slice(*SUB_LAYER_KEYS[layer])
|
58
|
+
.each { |k, v| merge_sub_layer_data(sub_layer_data, layer, k, v) }
|
62
59
|
sub_layer_data
|
63
60
|
end
|
64
61
|
|
65
62
|
def merge_sub_layer_data(sub_layer_data, layer, key, value)
|
66
63
|
if SUB_LAYER_KEY_MAP[layer].key?(key)
|
67
|
-
|
64
|
+
sub_layer_data
|
65
|
+
.concat([SUB_LAYER_KEY_MAP[layer][key]].product(value))
|
68
66
|
else
|
69
|
-
|
67
|
+
sub_layer_data << [key, value]
|
70
68
|
end
|
71
69
|
end
|
72
70
|
|
@@ -15,11 +15,13 @@ module RgGen
|
|
15
15
|
attr_reader :indent
|
16
16
|
|
17
17
|
def <<(rhs)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
case rhs
|
19
|
+
when String then push_string(rhs)
|
20
|
+
when CodeBlock then push_code_block(rhs)
|
21
|
+
when Array then rhs.inject(self, :<<)
|
22
|
+
when code? then self << rhs.to_code
|
23
|
+
else push_word(rhs)
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
def indent=(indent)
|
@@ -74,6 +76,10 @@ module RgGen
|
|
74
76
|
self
|
75
77
|
end
|
76
78
|
|
79
|
+
def code?
|
80
|
+
->(rhs) { rhs.respond_to?(:to_code) }
|
81
|
+
end
|
82
|
+
|
77
83
|
def newline
|
78
84
|
"\n"
|
79
85
|
end
|
data/lib/rggen/core/version.rb
CHANGED
data/lib/rggen/core.rb
CHANGED
@@ -27,7 +27,6 @@ require_relative 'core/utility/regexp_patterns'
|
|
27
27
|
|
28
28
|
require_relative 'core/exceptions'
|
29
29
|
|
30
|
-
require_relative 'core/base/proxy_call'
|
31
30
|
require_relative 'core/base/internal_struct'
|
32
31
|
require_relative 'core/base/shared_context'
|
33
32
|
require_relative 'core/base/component'
|
@@ -87,6 +86,8 @@ require_relative 'core/output_base/file_writer'
|
|
87
86
|
require_relative 'core/output_base/raise_error'
|
88
87
|
require_relative 'core/output_base/component'
|
89
88
|
require_relative 'core/output_base/component_factory'
|
89
|
+
require_relative 'core/output_base/source_file_component_factory'
|
90
|
+
require_relative 'core/output_base/document_component_factory'
|
90
91
|
require_relative 'core/output_base/feature'
|
91
92
|
require_relative 'core/output_base/feature_factory'
|
92
93
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rggen-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Taichi Ishitani
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docile
|
@@ -106,7 +106,6 @@ files:
|
|
106
106
|
- lib/rggen/core/base/feature_factory.rb
|
107
107
|
- lib/rggen/core/base/feature_layer_extension.rb
|
108
108
|
- lib/rggen/core/base/internal_struct.rb
|
109
|
-
- lib/rggen/core/base/proxy_call.rb
|
110
109
|
- lib/rggen/core/base/shared_context.rb
|
111
110
|
- lib/rggen/core/builder.rb
|
112
111
|
- lib/rggen/core/builder/builder.rb
|
@@ -158,11 +157,13 @@ files:
|
|
158
157
|
- lib/rggen/core/output_base/code_generator.rb
|
159
158
|
- lib/rggen/core/output_base/component.rb
|
160
159
|
- lib/rggen/core/output_base/component_factory.rb
|
160
|
+
- lib/rggen/core/output_base/document_component_factory.rb
|
161
161
|
- lib/rggen/core/output_base/erb_engine.rb
|
162
162
|
- lib/rggen/core/output_base/feature.rb
|
163
163
|
- lib/rggen/core/output_base/feature_factory.rb
|
164
164
|
- lib/rggen/core/output_base/file_writer.rb
|
165
165
|
- lib/rggen/core/output_base/raise_error.rb
|
166
|
+
- lib/rggen/core/output_base/source_file_component_factory.rb
|
166
167
|
- lib/rggen/core/output_base/template_engine.rb
|
167
168
|
- lib/rggen/core/plugin.rb
|
168
169
|
- lib/rggen/core/printers.rb
|
@@ -194,6 +195,7 @@ licenses:
|
|
194
195
|
metadata:
|
195
196
|
bug_tracker_uri: https://github.com/rggen/rggen-core/issues
|
196
197
|
mailing_list_uri: https://groups.google.com/d/forum/rggen
|
198
|
+
rubygems_mfa_required: 'true'
|
197
199
|
source_code_uri: https://github.com/rggen/rggen-core
|
198
200
|
wiki_uri: https://github.com/rggen/rggen/wiki
|
199
201
|
post_install_message:
|
@@ -204,15 +206,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
206
|
requirements:
|
205
207
|
- - ">="
|
206
208
|
- !ruby/object:Gem::Version
|
207
|
-
version: '2.
|
209
|
+
version: '2.6'
|
208
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
211
|
requirements:
|
210
212
|
- - ">="
|
211
213
|
- !ruby/object:Gem::Version
|
212
214
|
version: '0'
|
213
215
|
requirements: []
|
214
|
-
rubygems_version: 3.
|
216
|
+
rubygems_version: 3.3.3
|
215
217
|
signing_key:
|
216
218
|
specification_version: 4
|
217
|
-
summary: rggen-core-0.
|
219
|
+
summary: rggen-core-0.26.0
|
218
220
|
test_files: []
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RgGen
|
4
|
-
module Core
|
5
|
-
module Base
|
6
|
-
class ProxyCall
|
7
|
-
def initialize(receiver, method)
|
8
|
-
@receiver = receiver
|
9
|
-
@method = method
|
10
|
-
end
|
11
|
-
|
12
|
-
def call(*args, &block)
|
13
|
-
@receiver.__send__(@method, *args, &block)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|