ducktrap 0.0.1
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/.circle.yml +6 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +6 -0
- data/Gemfile.devtools +59 -0
- data/Guardfile +18 -0
- data/LICENSE +20 -0
- data/README.md +47 -0
- data/Rakefile +2 -0
- data/TODO +4 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/heckle.yml +3 -0
- data/config/mutant.yml +2 -0
- data/config/reek.yml +98 -0
- data/config/yardstick.yml +2 -0
- data/ducktrap.gemspec +23 -0
- data/lib/ducktrap.rb +73 -0
- data/lib/ducktrap/builder.rb +36 -0
- data/lib/ducktrap/error.rb +48 -0
- data/lib/ducktrap/evaluator.rb +127 -0
- data/lib/ducktrap/evaluator/invalid.rb +30 -0
- data/lib/ducktrap/evaluator/static.rb +25 -0
- data/lib/ducktrap/formatter.rb +138 -0
- data/lib/ducktrap/mapper.rb +59 -0
- data/lib/ducktrap/nary.rb +148 -0
- data/lib/ducktrap/node.rb +94 -0
- data/lib/ducktrap/node/anima.rb +40 -0
- data/lib/ducktrap/node/anima/dump.rb +39 -0
- data/lib/ducktrap/node/anima/load.rb +39 -0
- data/lib/ducktrap/node/block.rb +44 -0
- data/lib/ducktrap/node/coercion.rb +7 -0
- data/lib/ducktrap/node/custom.rb +121 -0
- data/lib/ducktrap/node/disjunction.rb +8 -0
- data/lib/ducktrap/node/forward.rb +55 -0
- data/lib/ducktrap/node/guard_nil.rb +42 -0
- data/lib/ducktrap/node/hash.rb +7 -0
- data/lib/ducktrap/node/hash/transform.rb +53 -0
- data/lib/ducktrap/node/invalid.rb +29 -0
- data/lib/ducktrap/node/inverse.rb +46 -0
- data/lib/ducktrap/node/key.rb +61 -0
- data/lib/ducktrap/node/key/add.rb +42 -0
- data/lib/ducktrap/node/key/delete.rb +44 -0
- data/lib/ducktrap/node/key/dump.rb +38 -0
- data/lib/ducktrap/node/key/fetch.rb +49 -0
- data/lib/ducktrap/node/map.rb +42 -0
- data/lib/ducktrap/node/noop.rb +30 -0
- data/lib/ducktrap/node/primitive.rb +61 -0
- data/lib/ducktrap/node/static.rb +33 -0
- data/lib/ducktrap/nullary.rb +41 -0
- data/lib/ducktrap/pretty_dump.rb +31 -0
- data/lib/ducktrap/registry.rb +60 -0
- data/lib/ducktrap/singleton.rb +55 -0
- data/lib/ducktrap/unary.rb +153 -0
- data/spec/rcov.opts +7 -0
- data/spec/shared/inverse_behavior.rb +7 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/ice_nine_config.rb +8 -0
- data/spec/support/let_mock_helper.rb +13 -0
- data/spec/unit/ducktrap/builder/class_methods/new_spec.rb +41 -0
- data/spec/unit/ducktrap/builder/new_spec.rb +41 -0
- data/spec/unit/ducktrap/class_methods/build_spec.rb +11 -0
- data/spec/unit/ducktrap/error/exception/pretty_inspect_spec.rb +22 -0
- data/spec/unit/ducktrap/error/pretty_inspect_spec.rb +19 -0
- data/spec/unit/ducktrap/evaluator/assert_successful_spec.rb +38 -0
- data/spec/unit/ducktrap/evaluator/invalid/output_spec.rb +14 -0
- data/spec/unit/ducktrap/evaluator/noop/output_spec.rb +14 -0
- data/spec/unit/ducktrap/evaluator/output_spec.rb +52 -0
- data/spec/unit/ducktrap/evaluator/pretty_inspect_spec.rb +63 -0
- data/spec/unit/ducktrap/evaluator/successful_predicate_spec.rb +36 -0
- data/spec/unit/ducktrap/failed_transformation_error/message_spec.rb +10 -0
- data/spec/unit/ducktrap/formatter/attribute_spec.rb +24 -0
- data/spec/unit/ducktrap/formatter/body_spec.rb +19 -0
- data/spec/unit/ducktrap/formatter/class_methods/new_spec.rb +14 -0
- data/spec/unit/ducktrap/formatter/initialize_spec.rb +14 -0
- data/spec/unit/ducktrap/formatter/name_spec.rb +25 -0
- data/spec/unit/ducktrap/formatter/nest_spec.rb +48 -0
- data/spec/unit/ducktrap/formatter/puts_spec.rb +36 -0
- data/spec/unit/ducktrap/mapper/builder/dumper_spec.rb +20 -0
- data/spec/unit/ducktrap/mapper/builder/loader_spec.rb +20 -0
- data/spec/unit/ducktrap/mapper/builder/object_spec.rb +90 -0
- data/spec/unit/ducktrap/mapper/class_methods/build_spec.rb +20 -0
- data/spec/unit/ducktrap/nary/builder/add_spec.rb +16 -0
- data/spec/unit/ducktrap/nary/builder/method_missing_spec.rb +44 -0
- data/spec/unit/ducktrap/nary/builder/output_spec.rb +16 -0
- data/spec/unit/ducktrap/nary/class_methods/build_spec.rb +22 -0
- data/spec/unit/ducktrap/nary/class_methods/included_spec.rb +13 -0
- data/spec/unit/ducktrap/nary/evaluator/output_spec.rb +79 -0
- data/spec/unit/ducktrap/nary/instance_methods/inverse_spec.rb +24 -0
- data/spec/unit/ducktrap/nary/instance_methods/pretty_inspect_spec.rb +31 -0
- data/spec/unit/ducktrap/node/anima/dump/evaluator/output_spec.rb +18 -0
- data/spec/unit/ducktrap/node/anima/dump/inverse_spec.rb +10 -0
- data/spec/unit/ducktrap/node/anima/dump/pretty_inspect_spec.rb +15 -0
- data/spec/unit/ducktrap/node/anima/evaluator/output_spec.rb +18 -0
- data/spec/unit/ducktrap/node/anima/load/evaluator/output_spec.rb +35 -0
- data/spec/unit/ducktrap/node/anima/load/inverse_spec.rb +10 -0
- data/spec/unit/ducktrap/node/anima/load/pretty_inspect_spec.rb +15 -0
- data/spec/unit/ducktrap/node/anima/pretty_inspect_spec.rb +15 -0
- data/spec/unit/ducktrap/node/block/evaluator/output_spec.rb +79 -0
- data/spec/unit/ducktrap/node/block/inverse_spec.rb +24 -0
- data/spec/unit/ducktrap/node/call_spec.rb +21 -0
- data/spec/unit/ducktrap/node/class_methods/build_spec.rb +11 -0
- data/spec/unit/ducktrap/node/class_methods/register_spec.rb +16 -0
- data/spec/unit/ducktrap/node/custom/builder/forward_spec.rb +54 -0
- data/spec/unit/ducktrap/node/custom/builder/inverse_spec.rb +54 -0
- data/spec/unit/ducktrap/node/custom/builder/object_spec.rb +54 -0
- data/spec/unit/ducktrap/node/custom/call_spec.rb +21 -0
- data/spec/unit/ducktrap/node/custom/class_methods/build_spec.rb +20 -0
- data/spec/unit/ducktrap/node/custom/inverse_spec.rb +12 -0
- data/spec/unit/ducktrap/node/custom/pretty_inspect_spec.rb +15 -0
- data/spec/unit/ducktrap/node/forward/evaluator/output_spec.rb +13 -0
- data/spec/unit/ducktrap/node/forward/inverse_spec.rb +14 -0
- data/spec/unit/ducktrap/node/forward/pretty_inspect_spec.rb +19 -0
- data/spec/unit/ducktrap/node/guard_nil/call_spec.rb +21 -0
- data/spec/unit/ducktrap/node/guard_nil/evaluator/output_spec.rb +27 -0
- data/spec/unit/ducktrap/node/guard_nil/inverse_spec.rb +12 -0
- data/spec/unit/ducktrap/node/hash/transform/evaluator/output_spec.rb +51 -0
- data/spec/unit/ducktrap/node/hash/transform/inverse_spec.rb +27 -0
- data/spec/unit/ducktrap/node/invalid/call_spec.rb +13 -0
- data/spec/unit/ducktrap/node/invalid/inverse_spec.rb +11 -0
- data/spec/unit/ducktrap/node/inverse/call_spec.rb +11 -0
- data/spec/unit/ducktrap/node/inverse/inverse_spec.rb +14 -0
- data/spec/unit/ducktrap/node/inverse/pretty_inspect_spec.rb +19 -0
- data/spec/unit/ducktrap/node/key/add/call_spec.rb +15 -0
- data/spec/unit/ducktrap/node/key/add/evaluator/call_spec.rb +15 -0
- data/spec/unit/ducktrap/node/key/add/inverse_spec.rb +14 -0
- data/spec/unit/ducktrap/node/key/delete/call_spec.rb +13 -0
- data/spec/unit/ducktrap/node/key/delete/evaluator/call_spec.rb +13 -0
- data/spec/unit/ducktrap/node/key/delete/inverse_spec.rb +13 -0
- data/spec/unit/ducktrap/node/key/dump/evaluator/output_spec.rb +37 -0
- data/spec/unit/ducktrap/node/key/dump/inverse_spec.rb +14 -0
- data/spec/unit/ducktrap/node/key/evaluator/key_spec.rb +26 -0
- data/spec/unit/ducktrap/node/key/fetch/evaluator/output_spec.rb +48 -0
- data/spec/unit/ducktrap/node/key/fetch/inverse_spec.rb +14 -0
- data/spec/unit/ducktrap/node/key/pretty_inspect_spec.rb +20 -0
- data/spec/unit/ducktrap/node/map/evaluator/output_spec.rb +22 -0
- data/spec/unit/ducktrap/node/map/inverse_spec.rb +15 -0
- data/spec/unit/ducktrap/node/noop/call_spec.rb +11 -0
- data/spec/unit/ducktrap/node/noop/inverse_spec.rb +9 -0
- data/spec/unit/ducktrap/node/pretty_inspect_spec.rb +17 -0
- data/spec/unit/ducktrap/node/primitive/call_spec.rb +19 -0
- data/spec/unit/ducktrap/node/primitive/inverse_spec.rb +13 -0
- data/spec/unit/ducktrap/node/primitive/pretty_inspect_spec.rb +15 -0
- data/spec/unit/ducktrap/node/run_spec.rb +46 -0
- data/spec/unit/ducktrap/node/static/call_spec.rb +13 -0
- data/spec/unit/ducktrap/node/static/inverse_spec.rb +14 -0
- data/spec/unit/ducktrap/nullary/class_methods/build_spec.rb +37 -0
- data/spec/unit/ducktrap/nullary/class_methods/included_spec.rb +7 -0
- data/spec/unit/ducktrap/pretty_dump/pretty_dump_spec.rb +47 -0
- data/spec/unit/ducktrap/pretty_dump/pretty_inspect_spec.rb +22 -0
- data/spec/unit/ducktrap/registry/lookup_spec.rb +27 -0
- data/spec/unit/ducktrap/registry/register_spec.rb +21 -0
- data/spec/unit/ducktrap/singleton/class_methods/included_spec.rb +13 -0
- data/spec/unit/ducktrap/singleton/class_methods/instance_spec.rb +19 -0
- data/spec/unit/ducktrap/singleton/instance_methods/inspect_spec.rb +19 -0
- data/spec/unit/ducktrap/singleton/instance_methods/pretty_inspect_spec.rb +17 -0
- data/spec/unit/ducktrap/unary/class_methods/build_spec.rb +18 -0
- data/spec/unit/ducktrap/unary/class_methods/included_spec.rb +14 -0
- data/spec/unit/ducktrap/unary/evaluator/output2_spec.rb +48 -0
- data/spec/unit/ducktrap/unary/evaluator/output_spec.rb +37 -0
- data/spec/unit/ducktrap/unary/instance_methods/pretty_inspect_spec.rb +15 -0
- metadata +399 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
class Node
|
3
|
+
# Noope node, returns input as output
|
4
|
+
class Noop < self
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
register :noop
|
8
|
+
|
9
|
+
# Run ducktrap
|
10
|
+
#
|
11
|
+
# @param [Object] input
|
12
|
+
#
|
13
|
+
# @return [Evaluator]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
def call(input)
|
18
|
+
Evaluator::Noop.new(self, input)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return inverse ducktrap
|
22
|
+
#
|
23
|
+
# @return [Ducktrap]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
#
|
27
|
+
def inverse; self; end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
class Node
|
3
|
+
# Primitive check
|
4
|
+
class Primitive < self
|
5
|
+
include Concord::Public.new(:primitive)
|
6
|
+
|
7
|
+
register :primitive
|
8
|
+
|
9
|
+
# Run ducktrap in input
|
10
|
+
#
|
11
|
+
# @param [Object] input
|
12
|
+
#
|
13
|
+
# @return [Evaluator]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
def call(input)
|
18
|
+
unless input.kind_of?(primitive)
|
19
|
+
return Evaluator::Invalid.new(self, input)
|
20
|
+
end
|
21
|
+
|
22
|
+
Evaluator::Noop.new(self, input)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return inverse ducktrap
|
26
|
+
#
|
27
|
+
# @return [self]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
def inverse; self end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Perfrom pretty dump
|
36
|
+
#
|
37
|
+
# @param [Formatter] output
|
38
|
+
#
|
39
|
+
# @return [undefined]
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
#
|
43
|
+
def dump(output)
|
44
|
+
output.name(self)
|
45
|
+
output.attribute(:primitive, primitive)
|
46
|
+
end
|
47
|
+
|
48
|
+
class << self
|
49
|
+
|
50
|
+
# Build node
|
51
|
+
#
|
52
|
+
# @return [node]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
#
|
56
|
+
alias_method :build, :new
|
57
|
+
end
|
58
|
+
|
59
|
+
end # Primitive
|
60
|
+
end # node
|
61
|
+
end # Ducktrap
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
class Node
|
3
|
+
# Transformer with static output
|
4
|
+
class Static < self
|
5
|
+
include Nullary, Concord::Public.new(:value, :inverse_value)
|
6
|
+
|
7
|
+
register :static
|
8
|
+
|
9
|
+
# Run ducktrap on input
|
10
|
+
#
|
11
|
+
# @param [Object] input
|
12
|
+
#
|
13
|
+
# @return [Evaluator]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
def call(input)
|
18
|
+
Evaluator::Static.new(self, input, value)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return inverse ducktrap
|
22
|
+
#
|
23
|
+
# @return [Ducktrap]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
#
|
27
|
+
def inverse
|
28
|
+
Static.new(inverse_value, value)
|
29
|
+
end
|
30
|
+
|
31
|
+
end # Static
|
32
|
+
end # Node
|
33
|
+
end # Ducktrap
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
# Mixin for defining nullary ducktraps
|
3
|
+
module Nullary
|
4
|
+
# Class method mixin
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
# Build ducktrap
|
8
|
+
#
|
9
|
+
# @return [Ducktrap]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
#
|
13
|
+
def build(*args)
|
14
|
+
if block_given?
|
15
|
+
raise "#{name}.build does not take a block"
|
16
|
+
end
|
17
|
+
new(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
end # ClassMethods
|
21
|
+
|
22
|
+
# Hook called when module is included
|
23
|
+
#
|
24
|
+
# @param [Module] scope
|
25
|
+
#
|
26
|
+
# @return [undefined]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
#
|
30
|
+
def self.included(scope)
|
31
|
+
scope.extend(ClassMethods)
|
32
|
+
end
|
33
|
+
private_class_method :included
|
34
|
+
|
35
|
+
# Evaluator for nullary nodes
|
36
|
+
class Evaluator < Ducktrap::Evaluator
|
37
|
+
|
38
|
+
end # Evaluator
|
39
|
+
|
40
|
+
end # Nullary
|
41
|
+
end # Ducktrap
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
# Mixin for pretty dumpable objects
|
3
|
+
module PrettyDump
|
4
|
+
|
5
|
+
# Perform pretty dump of ducktrap
|
6
|
+
#
|
7
|
+
# @return [self]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
#
|
11
|
+
def pretty_dump(output=Formatter.new)
|
12
|
+
dump(output)
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
# Return pretty inspection
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
#
|
22
|
+
def pretty_inspect
|
23
|
+
io = StringIO.new
|
24
|
+
formatter = Formatter.new(io)
|
25
|
+
pretty_dump(formatter)
|
26
|
+
io.rewind
|
27
|
+
io.read
|
28
|
+
end
|
29
|
+
|
30
|
+
end # PrettyDump
|
31
|
+
end # Ducktrap
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
|
3
|
+
# Registry for ducktraps
|
4
|
+
class Registry
|
5
|
+
|
6
|
+
# Register ducktrap under name
|
7
|
+
#
|
8
|
+
# @param [Symbol] name
|
9
|
+
# @param [Ducktrap] ducktrap
|
10
|
+
#
|
11
|
+
# @return [self]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
#
|
15
|
+
def register(name, ducktrap)
|
16
|
+
if @index.key?(name)
|
17
|
+
raise "name: #{name.inspect} does already exist"
|
18
|
+
end
|
19
|
+
|
20
|
+
@index[name] = ducktrap
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# Lookup ducktrap for name
|
26
|
+
#
|
27
|
+
# @param [Symbol] name
|
28
|
+
#
|
29
|
+
# @return [Ducktrap]
|
30
|
+
# if found
|
31
|
+
#
|
32
|
+
# @return [self]
|
33
|
+
# otherwise
|
34
|
+
#
|
35
|
+
# @yield
|
36
|
+
# if no ducktrap found for name
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
#
|
40
|
+
def lookup(name)
|
41
|
+
@index.fetch(name) do
|
42
|
+
yield
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Initialize object
|
49
|
+
#
|
50
|
+
# @return [undefined]
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
#
|
54
|
+
def initialize
|
55
|
+
@index = {}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
DSL = Registry.new
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
# Mixin to define nullary ducktraps
|
3
|
+
module Singleton
|
4
|
+
module InstanceMethods
|
5
|
+
include Adamantium::Flat
|
6
|
+
|
7
|
+
# Return inspect string
|
8
|
+
#
|
9
|
+
# @return [String]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
#
|
13
|
+
def inspect
|
14
|
+
"<#{self.class.name}>"
|
15
|
+
end
|
16
|
+
memoize :inspect
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
end # InstanceMethods
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
|
24
|
+
# Return instance
|
25
|
+
#
|
26
|
+
# @return [Ducktrap]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
#
|
30
|
+
def instance
|
31
|
+
@instance ||= new
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :build, :instance
|
35
|
+
|
36
|
+
end # ClassMethods
|
37
|
+
|
38
|
+
# Hook called when module is included
|
39
|
+
#
|
40
|
+
# @param [Module] scope
|
41
|
+
#
|
42
|
+
# @return [undefined]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
def self.included(scope)
|
47
|
+
scope.module_eval do
|
48
|
+
extend ClassMethods
|
49
|
+
include InstanceMethods
|
50
|
+
private_class_method :new
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end # Singleton
|
55
|
+
end # Ducktrap
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Ducktrap
|
2
|
+
# Mixin for defining unary ducktraps
|
3
|
+
module Unary
|
4
|
+
# Instance methods mixin for unary ducktraps
|
5
|
+
module InstanceMethods
|
6
|
+
|
7
|
+
# Return ducktrap
|
8
|
+
#
|
9
|
+
# @return [Ducktrap]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
#
|
13
|
+
attr_reader :operand
|
14
|
+
|
15
|
+
# Initialize object
|
16
|
+
#
|
17
|
+
# @param [Ducktrap] operand
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
#
|
21
|
+
def initialize(operand)
|
22
|
+
@operand = operand
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Perform pretty dump
|
28
|
+
#
|
29
|
+
# @return [undefined]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
#
|
33
|
+
def dump(output)
|
34
|
+
output.name(self)
|
35
|
+
output.nest(:operand, operand)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
|
42
|
+
# Build ducktrap
|
43
|
+
#
|
44
|
+
# @return [Ducktrap]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
#
|
48
|
+
def build(*args, &block)
|
49
|
+
postprocessor = Node::Noop.instance
|
50
|
+
if block
|
51
|
+
postprocessor = Node::Block.build(&block)
|
52
|
+
end
|
53
|
+
new(postprocessor, *args)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
# Hook called when module is included
|
59
|
+
#
|
60
|
+
# @param [Module] scope
|
61
|
+
#
|
62
|
+
# @return [undefined]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
#
|
66
|
+
def self.included(scope)
|
67
|
+
scope.module_eval do
|
68
|
+
include InstanceMethods, Equalizer.new(:operand)
|
69
|
+
extend ClassMethods
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private_class_method :included
|
74
|
+
|
75
|
+
# Evaluator for unary nodes
|
76
|
+
class Evaluator < Ducktrap::Evaluator
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Return operand
|
81
|
+
#
|
82
|
+
# @return [Ducktrap]
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
def operand
|
87
|
+
context.operand
|
88
|
+
end
|
89
|
+
|
90
|
+
# Process operand
|
91
|
+
#
|
92
|
+
# @param [Object] input
|
93
|
+
#
|
94
|
+
# @return [Evaluator]
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
#
|
98
|
+
def process_operand(input)
|
99
|
+
operand.call(input)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Process input with operand
|
103
|
+
#
|
104
|
+
# @return [Evaluator]
|
105
|
+
#
|
106
|
+
# @api private
|
107
|
+
#
|
108
|
+
def operand_evaluator
|
109
|
+
process_operand(input)
|
110
|
+
end
|
111
|
+
memoize :operand_evaluator
|
112
|
+
|
113
|
+
# Return operand output
|
114
|
+
#
|
115
|
+
# @return [Object]
|
116
|
+
#
|
117
|
+
# @api private
|
118
|
+
#
|
119
|
+
def operand_output
|
120
|
+
operand_evaluator.output
|
121
|
+
end
|
122
|
+
|
123
|
+
# Process input
|
124
|
+
#
|
125
|
+
# @param [Object]
|
126
|
+
#
|
127
|
+
# @return [Object]
|
128
|
+
# if successful
|
129
|
+
#
|
130
|
+
# @return [Error]
|
131
|
+
# otherwise
|
132
|
+
#
|
133
|
+
# @api private
|
134
|
+
#
|
135
|
+
def process
|
136
|
+
evaluator = operand_evaluator
|
137
|
+
unless evaluator.successful?
|
138
|
+
return nested_error(evaluator)
|
139
|
+
end
|
140
|
+
process_operand_output
|
141
|
+
end
|
142
|
+
|
143
|
+
# Process operand output
|
144
|
+
#
|
145
|
+
# @return [Object]
|
146
|
+
#
|
147
|
+
# @api private
|
148
|
+
#
|
149
|
+
abstract_method :process_operand_output
|
150
|
+
|
151
|
+
end # Evaluator
|
152
|
+
end # Unary
|
153
|
+
end # Ducktrap
|