rom 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -8
- data/CHANGELOG.md +28 -1
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +2 -2
- data/lib/rom.rb +1 -1
- data/lib/rom/command.rb +7 -5
- data/lib/rom/command_registry.rb +1 -1
- data/lib/rom/commands.rb +0 -2
- data/lib/rom/commands/abstract.rb +55 -25
- data/lib/rom/commands/composite.rb +13 -1
- data/lib/rom/commands/delete.rb +0 -8
- data/lib/rom/commands/graph.rb +102 -0
- data/lib/rom/commands/graph/class_interface.rb +69 -0
- data/lib/rom/commands/lazy.rb +87 -0
- data/lib/rom/constants.rb +22 -0
- data/lib/rom/env.rb +48 -18
- data/lib/rom/gateway.rb +132 -0
- data/lib/rom/global.rb +19 -19
- data/lib/rom/header.rb +42 -16
- data/lib/rom/header/attribute.rb +37 -15
- data/lib/rom/lint/gateway.rb +94 -0
- data/lib/rom/lint/spec.rb +15 -3
- data/lib/rom/lint/test.rb +45 -14
- data/lib/rom/mapper.rb +23 -10
- data/lib/rom/mapper/attribute_dsl.rb +157 -18
- data/lib/rom/memory.rb +1 -1
- data/lib/rom/memory/commands.rb +10 -8
- data/lib/rom/memory/dataset.rb +22 -2
- data/lib/rom/memory/{repository.rb → gateway.rb} +10 -10
- data/lib/rom/pipeline.rb +2 -1
- data/lib/rom/processor/transproc.rb +105 -14
- data/lib/rom/relation.rb +4 -4
- data/lib/rom/relation/class_interface.rb +19 -13
- data/lib/rom/relation/graph.rb +22 -0
- data/lib/rom/relation/lazy.rb +5 -3
- data/lib/rom/repository.rb +9 -118
- data/lib/rom/setup.rb +21 -14
- data/lib/rom/setup/finalize.rb +19 -19
- data/lib/rom/setup_dsl/relation.rb +10 -1
- data/lib/rom/support/deprecations.rb +21 -3
- data/lib/rom/support/enumerable_dataset.rb +1 -1
- data/lib/rom/version.rb +1 -1
- data/rom.gemspec +2 -4
- data/spec/integration/commands/delete_spec.rb +6 -0
- data/spec/integration/commands/graph_spec.rb +235 -0
- data/spec/integration/mappers/combine_spec.rb +14 -5
- data/spec/integration/mappers/definition_dsl_spec.rb +6 -1
- data/spec/integration/mappers/exclude_spec.rb +28 -0
- data/spec/integration/mappers/fold_spec.rb +16 -0
- data/spec/integration/mappers/group_spec.rb +0 -22
- data/spec/integration/mappers/prefix_separator_spec.rb +54 -0
- data/spec/integration/mappers/prefix_spec.rb +50 -0
- data/spec/integration/mappers/reusing_mappers_spec.rb +21 -0
- data/spec/integration/mappers/step_spec.rb +120 -0
- data/spec/integration/mappers/unfold_spec.rb +93 -0
- data/spec/integration/mappers/ungroup_spec.rb +127 -0
- data/spec/integration/mappers/unwrap_spec.rb +2 -2
- data/spec/integration/multi_repo_spec.rb +11 -11
- data/spec/integration/repositories/setting_logger_spec.rb +2 -2
- data/spec/integration/setup_spec.rb +11 -1
- data/spec/shared/command_behavior.rb +18 -0
- data/spec/shared/materializable.rb +4 -2
- data/spec/shared/users_and_tasks.rb +3 -3
- data/spec/test/memory_repository_lint_test.rb +4 -4
- data/spec/unit/rom/commands/graph_spec.rb +198 -0
- data/spec/unit/rom/commands/lazy_spec.rb +88 -0
- data/spec/unit/rom/commands_spec.rb +2 -2
- data/spec/unit/rom/env_spec.rb +26 -0
- data/spec/unit/rom/gateway_spec.rb +90 -0
- data/spec/unit/rom/global_spec.rb +4 -3
- data/spec/unit/rom/mapper/dsl_spec.rb +42 -1
- data/spec/unit/rom/mapper_spec.rb +4 -1
- data/spec/unit/rom/memory/commands/create_spec.rb +21 -0
- data/spec/unit/rom/memory/commands/delete_spec.rb +21 -0
- data/spec/unit/rom/memory/commands/update_spec.rb +21 -0
- data/spec/unit/rom/memory/relation_spec.rb +42 -10
- data/spec/unit/rom/memory/repository_spec.rb +3 -3
- data/spec/unit/rom/processor/transproc_spec.rb +75 -0
- data/spec/unit/rom/relation/lazy/combine_spec.rb +33 -4
- data/spec/unit/rom/relation/lazy_spec.rb +9 -1
- data/spec/unit/rom/repository_spec.rb +4 -63
- data/spec/unit/rom/setup_spec.rb +19 -5
- metadata +28 -38
- data/.ruby-version +0 -1
- data/lib/rom/lint/repository.rb +0 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f71a2cbfa094787fbd2ca709cd2c229aca10799
|
4
|
+
data.tar.gz: 73f461e9a6e50aec0d632f4332137fc389d57a70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a74fec1aaf8c1d5f0feb8b2128fa4db3c0ec31cf7018f8905ef396e3a614d071f17d7f60f2bd3411ca887efdbb9959faa3e73f0082fa3cbedcf43a95efd93286
|
7
|
+
data.tar.gz: 1ad96805142be1ac15bb329109e251c8c4170ce2c42f6fc409b7351899bb8ae283686241b414a7f1ff1bb08dc4b1b10f0ff59da2ad4e0d46f2e3c8e90f1dbf62
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -5,6 +5,7 @@ inherit_from: .rubocop_todo.yml
|
|
5
5
|
AllCops:
|
6
6
|
Exclude:
|
7
7
|
- tmp/**/*
|
8
|
+
- vendor/**/*
|
8
9
|
|
9
10
|
Style/BlockDelimiters:
|
10
11
|
EnforcedStyle: semantic
|
@@ -35,10 +36,6 @@ Style/AlignParameters:
|
|
35
36
|
Style/AsciiComments:
|
36
37
|
Enabled: false
|
37
38
|
|
38
|
-
# Allow using braces for value-returning blocks
|
39
|
-
Style/Blocks:
|
40
|
-
Enabled: false
|
41
|
-
|
42
39
|
# Documentation checked by Inch CI
|
43
40
|
Style/Documentation:
|
44
41
|
Enabled: false
|
@@ -55,15 +52,15 @@ Style/Lambda:
|
|
55
52
|
Style/MultilineBlockChain:
|
56
53
|
Enabled: false
|
57
54
|
|
55
|
+
# Multiline operation chains are indented
|
56
|
+
Style/MultilineOperationIndentation:
|
57
|
+
EnforcedStyle: indented
|
58
|
+
|
58
59
|
# Result::Success and Result::Failure use > for callbacks
|
59
60
|
Style/OpMethod:
|
60
61
|
Exclude:
|
61
62
|
- lib/rom/command_registry.rb
|
62
63
|
|
63
|
-
# Even a single escaped slash can be confusing
|
64
|
-
Style/RegexpLiteral:
|
65
|
-
MaxSlashes: 0
|
66
|
-
|
67
64
|
# Don’t introduce semantic fail/raise distinction
|
68
65
|
Style/SignalException:
|
69
66
|
EnforcedStyle: only_raise
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
## v0.8.0 2015-06-22
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* New `step` mapper operation that allows multistep transformations inside a single mapper (dekz)
|
6
|
+
* New `ungroup` and `unfold` mapper operations inverse `group` and `fold` (nepalez)
|
7
|
+
* Support deep nesting of `unwrap` mapper operations (nepalez)
|
8
|
+
* Support usage of `exclude` in a root of the mapper (nepalez)
|
9
|
+
* Support usage of `prefix` and `prefix_separator` mapper operations inside blocks (nepalez)
|
10
|
+
* Support renaming of the rest of an attribute after `unwrap` (nepalez)
|
11
|
+
|
12
|
+
### Changed
|
13
|
+
|
14
|
+
* `Repository` class has been renamed to `Gateway` with proper deprecation
|
15
|
+
warnings (cflipse)
|
16
|
+
* `combine` in mapper can be used without a block (kwando)
|
17
|
+
* `wrap` and `group` in mapper will raise error if `:mapper` is set along with
|
18
|
+
block or options (vrish88)
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
|
22
|
+
* `order` memory repository operation sorts tuples containing empty values (nepalez)
|
23
|
+
* `Mapper::AttributeDSL#embedded` now honors `option[:type]` when used
|
24
|
+
with `option[:mapper]` (c0)
|
25
|
+
|
26
|
+
[Compare v0.7.1...v0.8.0](https://github.com/rom-rb/rom/compare/v0.7.1...v0.8.0)
|
27
|
+
|
1
28
|
## v0.7.1 2015-05-22
|
2
29
|
|
3
30
|
### Added
|
@@ -14,7 +41,7 @@
|
|
14
41
|
* [rom/memory] `restrict` operation supports array as a value (gotar)
|
15
42
|
* [rom/memory] `restrict` operation supports regexp as a value (gotar)
|
16
43
|
|
17
|
-
[Compare v0.7.0...
|
44
|
+
[Compare v0.7.0...v0.7.1](https://github.com/rom-rb/rom/compare/v0.7.0...v0.7.1)
|
18
45
|
|
19
46
|
## v0.7.0 2015-05-17
|
20
47
|
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
CHANGED
@@ -34,7 +34,7 @@ group :benchmarks do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
group :tools do
|
37
|
-
gem 'rubocop'
|
37
|
+
gem 'rubocop', '~> 0.31'
|
38
38
|
|
39
39
|
gem 'guard'
|
40
40
|
gem 'guard-rspec'
|
@@ -43,7 +43,7 @@ group :tools do
|
|
43
43
|
gem 'byebug'
|
44
44
|
|
45
45
|
platform :mri do
|
46
|
-
gem 'mutant', '>= 0.
|
46
|
+
gem 'mutant', '>= 0.8.0', github: 'mbj/mutant', branch: 'master'
|
47
47
|
gem 'mutant-rspec'
|
48
48
|
end
|
49
49
|
end
|
data/lib/rom.rb
CHANGED
data/lib/rom/command.rb
CHANGED
@@ -50,6 +50,8 @@ module ROM
|
|
50
50
|
# @api private
|
51
51
|
def self.adapter_namespace(adapter)
|
52
52
|
ROM.adapters.fetch(adapter).const_get(:Commands)
|
53
|
+
rescue KeyError
|
54
|
+
raise AdapterNotPresentError.new(adapter, :relation)
|
53
55
|
end
|
54
56
|
|
55
57
|
# Build a command class for a specific relation with options
|
@@ -84,20 +86,20 @@ module ROM
|
|
84
86
|
# @option options [Symbol] :adapter (:default) first adapter to check for plugin
|
85
87
|
#
|
86
88
|
# @api public
|
87
|
-
def self.use(plugin,
|
89
|
+
def self.use(plugin, _options = {})
|
88
90
|
ROM.plugin_registry.commands.fetch(plugin, adapter).apply_to(self)
|
89
91
|
end
|
90
92
|
|
91
93
|
# Build command registry hash for provided relations
|
92
94
|
#
|
93
95
|
# @param [RelationRegistry] relations registry
|
94
|
-
# @param [Hash]
|
96
|
+
# @param [Hash] gateways
|
95
97
|
# @param [Array] descendants a list of command subclasses
|
96
98
|
#
|
97
99
|
# @return [Hash]
|
98
100
|
#
|
99
101
|
# @api private
|
100
|
-
def self.registry(relations,
|
102
|
+
def self.registry(relations, gateways, descendants)
|
101
103
|
descendants.each_with_object({}) do |klass, h|
|
102
104
|
rel_name = klass.relation
|
103
105
|
|
@@ -106,8 +108,8 @@ module ROM
|
|
106
108
|
relation = relations[rel_name]
|
107
109
|
name = klass.register_as || klass.default_name
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
+
gateway = gateways[relation.class.gateway]
|
112
|
+
gateway.extend_command_class(klass, relation.dataset)
|
111
113
|
|
112
114
|
(h[rel_name] ||= {})[name] = klass.build(relation)
|
113
115
|
end
|
data/lib/rom/command_registry.rb
CHANGED
@@ -36,7 +36,7 @@ module ROM
|
|
36
36
|
# @example
|
37
37
|
#
|
38
38
|
# rom.command(:users).try { create(name: 'Jane') }
|
39
|
-
# rom.command(:users).try { update(:by_id, 1).
|
39
|
+
# rom.command(:users).try { update(:by_id, 1).call(name: 'Jane Doe') }
|
40
40
|
# rom.command(:users).try { delete(:by_id, 1) }
|
41
41
|
#
|
42
42
|
# @return [Commands::Result]
|
data/lib/rom/commands.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
+
require 'rom/support/deprecations'
|
2
|
+
|
1
3
|
require 'rom/commands/composite'
|
4
|
+
require 'rom/commands/graph'
|
5
|
+
require 'rom/commands/lazy'
|
2
6
|
|
3
7
|
module ROM
|
4
8
|
module Commands
|
@@ -15,20 +19,26 @@ module ROM
|
|
15
19
|
# @private
|
16
20
|
class Abstract
|
17
21
|
include Options
|
22
|
+
extend Deprecations
|
18
23
|
|
19
24
|
option :type, allow: [:create, :update, :delete]
|
25
|
+
option :source, reader: true
|
20
26
|
option :result, reader: true, allow: [:one, :many]
|
21
|
-
option :target
|
22
27
|
option :validator, reader: true
|
23
28
|
option :input, reader: true
|
24
29
|
option :curry_args, type: Array, reader: true, default: EMPTY_ARRAY
|
25
30
|
|
31
|
+
# @attr_reader [Relation] relation The command's relation
|
26
32
|
attr_reader :relation
|
27
33
|
|
34
|
+
deprecate :target, :relation,
|
35
|
+
'Source relation is now available as `Command#source`'
|
36
|
+
|
28
37
|
# @api private
|
29
38
|
def initialize(relation, options = {})
|
30
|
-
@relation = relation
|
31
39
|
super
|
40
|
+
@relation = relation
|
41
|
+
@source = options[:source] || relation
|
32
42
|
end
|
33
43
|
|
34
44
|
# Execute the command
|
@@ -51,7 +61,7 @@ module ROM
|
|
51
61
|
def call(*args)
|
52
62
|
tuples = execute(*(curry_args + args))
|
53
63
|
|
54
|
-
if
|
64
|
+
if one?
|
55
65
|
tuples.first
|
56
66
|
else
|
57
67
|
tuples
|
@@ -67,7 +77,11 @@ module ROM
|
|
67
77
|
#
|
68
78
|
# @api public
|
69
79
|
def curry(*args)
|
70
|
-
|
80
|
+
if curry_args.empty? && args.first.is_a?(Proc)
|
81
|
+
Lazy.new(self, args.first)
|
82
|
+
else
|
83
|
+
self.class.build(relation, options.merge(curry_args: args))
|
84
|
+
end
|
71
85
|
end
|
72
86
|
alias_method :with, :curry
|
73
87
|
|
@@ -89,48 +103,53 @@ module ROM
|
|
89
103
|
Composite.new(self, other)
|
90
104
|
end
|
91
105
|
|
92
|
-
#
|
93
|
-
|
106
|
+
# @api public
|
107
|
+
def combine(*others)
|
108
|
+
Graph.new(self, others)
|
109
|
+
end
|
110
|
+
|
94
111
|
# @api private
|
95
|
-
def
|
96
|
-
|
112
|
+
def lazy?
|
113
|
+
false
|
97
114
|
end
|
98
115
|
|
99
|
-
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
116
|
+
# @api private
|
117
|
+
def graph?
|
118
|
+
false
|
119
|
+
end
|
120
|
+
|
121
|
+
# @api private
|
122
|
+
def one?
|
123
|
+
result.equal?(:one)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @api private
|
127
|
+
def many?
|
128
|
+
result.equal?(:many)
|
110
129
|
end
|
111
130
|
|
112
|
-
# Assert that tuple count in the
|
131
|
+
# Assert that tuple count in the relation corresponds to :result
|
113
132
|
# setting
|
114
133
|
#
|
115
134
|
# @raise TupleCountMismatchError
|
116
135
|
#
|
117
136
|
# @api private
|
118
137
|
def assert_tuple_count
|
119
|
-
if
|
138
|
+
if one? && tuple_count > 1
|
120
139
|
raise TupleCountMismatchError, "#{inspect} expects one tuple"
|
121
140
|
end
|
122
141
|
end
|
123
142
|
|
124
|
-
# Return number of tuples in the
|
143
|
+
# Return number of tuples in the relation relation
|
125
144
|
#
|
126
|
-
# This should be overridden by
|
145
|
+
# This should be overridden by gateways when `#count` is not available
|
127
146
|
# in the relation objects
|
128
147
|
#
|
129
148
|
# @return [Fixnum]
|
130
149
|
#
|
131
150
|
# @api private
|
132
151
|
def tuple_count
|
133
|
-
|
152
|
+
relation.count
|
134
153
|
end
|
135
154
|
|
136
155
|
# @api private
|
@@ -138,12 +157,23 @@ module ROM
|
|
138
157
|
relation.respond_to?(name) || super
|
139
158
|
end
|
140
159
|
|
160
|
+
# @api private
|
161
|
+
def new(new_relation)
|
162
|
+
self.class.build(new_relation, options.merge(source: relation))
|
163
|
+
end
|
164
|
+
|
141
165
|
private
|
142
166
|
|
143
167
|
# @api private
|
144
168
|
def method_missing(name, *args, &block)
|
145
169
|
if relation.respond_to?(name)
|
146
|
-
|
170
|
+
response = relation.public_send(name, *args, &block)
|
171
|
+
|
172
|
+
if response.instance_of?(relation.class)
|
173
|
+
new(response)
|
174
|
+
else
|
175
|
+
response
|
176
|
+
end
|
147
177
|
else
|
148
178
|
super
|
149
179
|
end
|
@@ -14,22 +14,34 @@ module ROM
|
|
14
14
|
def call(*args)
|
15
15
|
response = left.call(*args)
|
16
16
|
|
17
|
-
if
|
17
|
+
if one? && !graph?
|
18
18
|
if right.is_a?(Command) || right.is_a?(Commands::Composite)
|
19
19
|
right.call([response].first)
|
20
20
|
else
|
21
21
|
right.call([response]).first
|
22
22
|
end
|
23
|
+
elsif one? && graph?
|
24
|
+
right.call(response).first
|
23
25
|
else
|
24
26
|
right.call(response)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
alias_method :[], :call
|
28
30
|
|
31
|
+
# @api private
|
32
|
+
def graph?
|
33
|
+
left.is_a?(Graph)
|
34
|
+
end
|
35
|
+
|
29
36
|
# @api private
|
30
37
|
def result
|
31
38
|
left.result
|
32
39
|
end
|
40
|
+
|
41
|
+
# @api private
|
42
|
+
def decorate?(response)
|
43
|
+
super || response.is_a?(Graph)
|
44
|
+
end
|
33
45
|
end
|
34
46
|
end
|
35
47
|
end
|
data/lib/rom/commands/delete.rb
CHANGED
@@ -8,14 +8,6 @@ module ROM
|
|
8
8
|
#
|
9
9
|
# @abstract
|
10
10
|
class Delete < Command
|
11
|
-
attr_reader :target
|
12
|
-
|
13
|
-
# @api private
|
14
|
-
def initialize(relation, options = {})
|
15
|
-
super
|
16
|
-
@target = options[:target] || relation
|
17
|
-
end
|
18
|
-
|
19
11
|
# @see AbstractCommand#call
|
20
12
|
def call(*args)
|
21
13
|
assert_tuple_count
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'rom/pipeline'
|
2
|
+
require 'rom/support/options'
|
3
|
+
require 'rom/commands/graph/class_interface'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module Commands
|
7
|
+
# Command graph
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Graph
|
11
|
+
extend ClassInterface
|
12
|
+
|
13
|
+
include Options
|
14
|
+
include Pipeline
|
15
|
+
include Pipeline::Proxy
|
16
|
+
|
17
|
+
# @attr_reader [Command] root The root command
|
18
|
+
attr_reader :root
|
19
|
+
|
20
|
+
# @attr_reader [Array<Command>] nodes The child commands
|
21
|
+
attr_reader :nodes
|
22
|
+
|
23
|
+
alias_method :left, :root
|
24
|
+
alias_method :right, :nodes
|
25
|
+
|
26
|
+
option :mappers, reader: true, default: proc { MapperRegistry.new }
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def initialize(root, nodes, options = {})
|
30
|
+
super
|
31
|
+
@root = root
|
32
|
+
@nodes = nodes
|
33
|
+
end
|
34
|
+
|
35
|
+
# Calls root and all nodes with the result from root
|
36
|
+
#
|
37
|
+
# Graph results are mappable through `combine` operation in mapper DSL
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# create_user = rom.command(:users).create
|
41
|
+
# create_task = rom.command(:tasks).create
|
42
|
+
#
|
43
|
+
# command = create_user
|
44
|
+
# .with(name: 'Jane')
|
45
|
+
# .combine(create_task.with(title: 'Task'))
|
46
|
+
#
|
47
|
+
# command.call
|
48
|
+
#
|
49
|
+
# @return [Array] nested array with command results
|
50
|
+
#
|
51
|
+
# @api public
|
52
|
+
def call(*args)
|
53
|
+
begin
|
54
|
+
left = root.call(*args)
|
55
|
+
|
56
|
+
right = nodes.map do |node|
|
57
|
+
begin
|
58
|
+
response =
|
59
|
+
if node.lazy?
|
60
|
+
node.call(args.first, left)
|
61
|
+
else
|
62
|
+
node.call(left)
|
63
|
+
end
|
64
|
+
rescue => err
|
65
|
+
raise CommandFailure.new(node, err)
|
66
|
+
rescue CommandFailure => err
|
67
|
+
raise err
|
68
|
+
end
|
69
|
+
|
70
|
+
if node.one? && !node.graph?
|
71
|
+
[response]
|
72
|
+
else
|
73
|
+
response
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if one?
|
78
|
+
[[left], right]
|
79
|
+
else
|
80
|
+
[left, right]
|
81
|
+
end
|
82
|
+
rescue => err
|
83
|
+
raise CommandFailure.new(root, err)
|
84
|
+
rescue CommandFailure => err
|
85
|
+
raise err
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Return a new graph with updated options
|
90
|
+
#
|
91
|
+
# @api private
|
92
|
+
def with(new_options)
|
93
|
+
self.class.new(root, nodes, options.merge(new_options))
|
94
|
+
end
|
95
|
+
|
96
|
+
# @api private
|
97
|
+
def graph?
|
98
|
+
true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|