sinclair 1.10.0 → 1.12.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 +4 -4
- data/.rubocop.yml +6 -0
- data/README.md +444 -324
- data/config/check_specs.yml +5 -5
- data/config/yardstick.yml +4 -0
- data/lib/sinclair/matchers/add_class_method.rb +0 -1
- data/lib/sinclair/method_builder/base.rb +32 -2
- data/lib/sinclair/method_builder/block_method_builder.rb +1 -12
- data/lib/sinclair/method_builder/call_method_builder.rb +10 -27
- data/lib/sinclair/method_builder/string_method_builder.rb +2 -29
- data/lib/sinclair/method_builder.rb +4 -20
- data/lib/sinclair/method_definition/block_definition.rb +2 -0
- data/lib/sinclair/method_definition/call_definition.rb +15 -18
- data/lib/sinclair/method_definition/parameter_builder.rb +89 -0
- data/lib/sinclair/method_definition/parameter_helper.rb +124 -0
- data/lib/sinclair/method_definition/string_definition.rb +26 -2
- data/lib/sinclair/method_definition.rb +42 -3
- data/lib/sinclair/method_definitions.rb +20 -22
- data/lib/sinclair/version.rb +1 -1
- data/lib/sinclair.rb +149 -62
- data/spec/integration/readme/sinclair/types_of_definition_spec.rb +61 -0
- data/spec/integration/yard/sinclair/add_class_method_spec.rb +51 -0
- data/spec/integration/yard/sinclair/add_method_spec.rb +60 -0
- data/spec/integration/yard/sinclair/eval_and_add_method_spec.rb +26 -0
- data/spec/integration/yard/sinclair_spec.rb +0 -83
- data/spec/lib/sinclair/method_builder/base_spec.rb +15 -0
- data/spec/lib/sinclair/method_builder/string_method_builder_spec.rb +24 -1
- data/spec/lib/sinclair/method_definition/call_definition_spec.rb +14 -17
- data/spec/lib/sinclair/method_definition/parameter_builder_spec.rb +81 -0
- data/spec/lib/sinclair/method_definition/string_definition_spec.rb +60 -29
- data/spec/lib/sinclair/method_definition_spec.rb +77 -2
- data/spec/lib/sinclair/method_definitions_spec.rb +15 -16
- data/spec/lib/sinclair_spec.rb +6 -160
- data/spec/support/models/dummy_builder.rb +5 -1
- data/spec/support/models/dummy_class_builder.rb +4 -0
- data/spec/support/models/person.rb +1 -1
- data/spec/support/shared_examples/sinclair.rb +118 -0
- metadata +11 -2
data/config/check_specs.yml
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
ignore:
|
2
2
|
- lib/sinclair/comparable/class_methods.rb
|
3
|
-
- lib/sinclair/matchers/add_method_to.rb
|
4
|
-
- lib/sinclair/matchers/add_method.rb
|
5
|
-
- lib/sinclair/version.rb
|
6
|
-
- lib/sinclair/method_builder/base.rb
|
7
3
|
- lib/sinclair/exception.rb
|
8
|
-
- lib/sinclair/matchers/
|
4
|
+
- lib/sinclair/matchers/add_method.rb
|
5
|
+
- lib/sinclair/matchers/add_method_to.rb
|
9
6
|
- lib/sinclair/matchers/base.rb
|
10
7
|
- lib/sinclair/matchers/change_method_on.rb
|
8
|
+
- lib/sinclair/matchers/method_to.rb
|
9
|
+
- lib/sinclair/method_definition/parameter_helper.rb
|
10
|
+
- lib/sinclair/version.rb
|
data/config/yardstick.yml
CHANGED
@@ -16,6 +16,8 @@ rules:
|
|
16
16
|
ExampleTag:
|
17
17
|
enabled: true
|
18
18
|
exclude:
|
19
|
+
- Sinclair#add_method
|
20
|
+
- Sinclair#add_class_method
|
19
21
|
- Sinclair::Configurable#config
|
20
22
|
- Sinclair::Configurable#reset_config
|
21
23
|
- Sinclair::Configurable#configure
|
@@ -58,6 +60,8 @@ rules:
|
|
58
60
|
- Sinclair::MethodDefinition#initialize
|
59
61
|
- Sinclair::MethodDefinition::CallDefinition#initialize
|
60
62
|
- Sinclair::MethodDefinition::BlockDefinition#initialize
|
63
|
+
- Sinclair::MethodDefinition::ParameterBuilder#initialize
|
64
|
+
- Sinclair::MethodDefinition::ParameterHelper#initialize
|
61
65
|
- Sinclair::MethodDefinition::StringDefinition#initialize
|
62
66
|
- Sinclair::Options#initialize
|
63
67
|
- Sinclair::Options::Builder#initialize
|
@@ -7,7 +7,6 @@ class Sinclair
|
|
7
7
|
#
|
8
8
|
# AddClassMethod is able to build an instance of {Sinclair::Matchers::AddClassMethodTo}
|
9
9
|
class AddClassMethod < AddMethod
|
10
|
-
# @method #to(target = nil)
|
11
10
|
# @example Checking if a class had a class method added
|
12
11
|
# RSpec.configure do |config|
|
13
12
|
# config.include Sinclair::Matchers
|
@@ -7,6 +7,21 @@ class Sinclair
|
|
7
7
|
#
|
8
8
|
# Base class responsible for building methods
|
9
9
|
class Base
|
10
|
+
# Instantiate the class and build the method
|
11
|
+
#
|
12
|
+
# @param klass [Class] class to receive the method
|
13
|
+
# @param definition [MethodDefinition] method defined
|
14
|
+
# @param type [Symbol] type of method to be build
|
15
|
+
# - +:instance+ instance methods
|
16
|
+
# - +:class+ class methods
|
17
|
+
#
|
18
|
+
# @see #build
|
19
|
+
#
|
20
|
+
# @return [Symbol] name of the method built
|
21
|
+
def self.build(klass, definition, type:)
|
22
|
+
new(klass, definition, type: type).build
|
23
|
+
end
|
24
|
+
|
10
25
|
# @param klass [Class] class to receive the method
|
11
26
|
# @param definition [MethodDefinition] method defined
|
12
27
|
# @param type [Symbol] type of method to be build
|
@@ -22,9 +37,9 @@ class Sinclair
|
|
22
37
|
#
|
23
38
|
# @return [Symbol] name of the method built
|
24
39
|
#
|
25
|
-
# @raise
|
40
|
+
# @raise NotImplementedError
|
26
41
|
def build
|
27
|
-
raise 'Not implemented yet. this should be imlemented in subclasses'
|
42
|
+
raise NotImplementedError, 'Not implemented yet. this should be imlemented in subclasses'
|
28
43
|
end
|
29
44
|
|
30
45
|
private
|
@@ -62,6 +77,21 @@ class Sinclair
|
|
62
77
|
def instance?
|
63
78
|
type == INSTANCE_METHOD
|
64
79
|
end
|
80
|
+
|
81
|
+
# Returns the klass where the proc block will be evaluated
|
82
|
+
#
|
83
|
+
# For instance type, the class itself is returned
|
84
|
+
#
|
85
|
+
# For adding class methods, the superclass is returned
|
86
|
+
#
|
87
|
+
# @return [Class]
|
88
|
+
def evaluating_class
|
89
|
+
return klass if instance?
|
90
|
+
|
91
|
+
class << klass
|
92
|
+
return self
|
93
|
+
end
|
94
|
+
end
|
65
95
|
end
|
66
96
|
end
|
67
97
|
end
|
@@ -14,21 +14,10 @@ class Sinclair
|
|
14
14
|
#
|
15
15
|
# @return (see Base#build)
|
16
16
|
def build
|
17
|
-
|
17
|
+
evaluating_class.define_method(name, method_block)
|
18
18
|
end
|
19
19
|
|
20
|
-
private
|
21
|
-
|
22
20
|
delegate :name, :method_block, to: :definition
|
23
|
-
|
24
|
-
# @private
|
25
|
-
#
|
26
|
-
# name of the method used to define a new method on class
|
27
|
-
#
|
28
|
-
# @return [Symbol]
|
29
|
-
def method_definition
|
30
|
-
instance? ? :define_method : :define_singleton_method
|
31
|
-
end
|
32
21
|
end
|
33
22
|
end
|
34
23
|
end
|
@@ -9,41 +9,24 @@ class Sinclair
|
|
9
9
|
class CallMethodBuilder < Base
|
10
10
|
# Builds the method
|
11
11
|
#
|
12
|
+
# The build uses +module_eval+ over a class
|
13
|
+
#
|
14
|
+
# The code is ran either on the class itself or in
|
15
|
+
# a block that allow creation of class methods
|
16
|
+
#
|
12
17
|
# @return [NilClass]
|
13
18
|
def build
|
14
|
-
|
19
|
+
evaluating_class.module_eval(&code_block)
|
15
20
|
end
|
16
21
|
|
17
|
-
|
18
|
-
|
22
|
+
delegate :code_block, to: :definition
|
23
|
+
# @method code_block
|
19
24
|
# @api private
|
20
25
|
# @private
|
21
26
|
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
# This can be {code_string} or {class_code_string}
|
25
|
-
# @return (see MethodDefinition::CallDefinition#code_string)
|
26
|
-
def code_line
|
27
|
-
instance? ? code_string : class_code_string
|
28
|
-
end
|
29
|
-
|
30
|
-
delegate :code_string, :class_code_string, to: :definition
|
31
|
-
|
32
|
-
# @method code_string
|
33
|
-
# @private
|
34
|
-
# @api private
|
35
|
-
#
|
36
|
-
# Delegated from {MethodDefinition::CallDefinition}
|
37
|
-
#
|
38
|
-
# @see MethodDefinition::CallDefinition#code_string
|
39
|
-
# @return [String]
|
40
|
-
|
41
|
-
# @method class_code_string
|
42
|
-
# @private
|
43
|
-
# @api private
|
27
|
+
# Code block to be evaluated by the class
|
44
28
|
#
|
45
|
-
# @
|
46
|
-
# @return [String]
|
29
|
+
# @return [Proc]
|
47
30
|
end
|
48
31
|
end
|
49
32
|
end
|
@@ -14,37 +14,10 @@ class Sinclair
|
|
14
14
|
#
|
15
15
|
# @return (see Base#build)
|
16
16
|
def build
|
17
|
-
|
17
|
+
evaluating_class.module_eval(code_definition, __FILE__, __LINE__ + 1)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
# @private
|
23
|
-
#
|
24
|
-
# string used for method name definition
|
25
|
-
#
|
26
|
-
# the string changes depending if it is
|
27
|
-
# a class or instance method
|
28
|
-
#
|
29
|
-
# @return [String]
|
30
|
-
def definition_name
|
31
|
-
instance? ? name : "self.#{name}"
|
32
|
-
end
|
33
|
-
|
34
|
-
# @private
|
35
|
-
#
|
36
|
-
# string with the code to be defined
|
37
|
-
#
|
38
|
-
# @return [String]
|
39
|
-
def code_definition
|
40
|
-
<<-CODE
|
41
|
-
def #{definition_name}
|
42
|
-
#{code_line}
|
43
|
-
end
|
44
|
-
CODE
|
45
|
-
end
|
46
|
-
|
47
|
-
delegate :code_line, :name, to: :definition
|
20
|
+
delegate :code_definition, to: :definition
|
48
21
|
end
|
49
22
|
end
|
50
23
|
end
|
@@ -7,9 +7,9 @@ class Sinclair
|
|
7
7
|
# Class responsible for building methods
|
8
8
|
class MethodBuilder
|
9
9
|
autoload :Base, 'sinclair/method_builder/base'
|
10
|
-
autoload :StringMethodBuilder, 'sinclair/method_builder/string_method_builder'
|
11
10
|
autoload :BlockMethodBuilder, 'sinclair/method_builder/block_method_builder'
|
12
11
|
autoload :CallMethodBuilder, 'sinclair/method_builder/call_method_builder'
|
12
|
+
autoload :StringMethodBuilder, 'sinclair/method_builder/string_method_builder'
|
13
13
|
|
14
14
|
CLASS_METHOD = :class
|
15
15
|
INSTANCE_METHOD = :instance
|
@@ -24,11 +24,13 @@ class Sinclair
|
|
24
24
|
# @param definitions [MethodDefinitions] all methods
|
25
25
|
# definitions to be built
|
26
26
|
# @param type [Symbol] type of method to be built
|
27
|
+
# - {CLASS_METHOD} : A class method will be built
|
28
|
+
# - {INSTANCE_METHOD} : An instance method will be built
|
27
29
|
#
|
28
30
|
# @return [MethodDefinitions]
|
29
31
|
def build_methods(definitions, type)
|
30
32
|
definitions.each do |definition|
|
31
|
-
|
33
|
+
definition.build(klass, type)
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
@@ -42,23 +44,5 @@ class Sinclair
|
|
42
44
|
# class to receive the method
|
43
45
|
#
|
44
46
|
# @return [Class]
|
45
|
-
|
46
|
-
# @private
|
47
|
-
#
|
48
|
-
# Build one method from definition
|
49
|
-
#
|
50
|
-
# @param definition [MethodDefinition] the method definition
|
51
|
-
# @param type [Symbol] type of method to be built
|
52
|
-
#
|
53
|
-
# @return (see Base#build)
|
54
|
-
def build_from_definition(definition, type)
|
55
|
-
if definition.string?
|
56
|
-
StringMethodBuilder.new(klass, definition, type: type).build
|
57
|
-
elsif definition.block?
|
58
|
-
BlockMethodBuilder.new(klass, definition, type: type).build
|
59
|
-
else
|
60
|
-
CallMethodBuilder.new(klass, definition, type: type).build
|
61
|
-
end
|
62
|
-
end
|
63
47
|
end
|
64
48
|
end
|
@@ -7,6 +7,8 @@ class Sinclair
|
|
7
7
|
#
|
8
8
|
# Define a method from block
|
9
9
|
class BlockDefinition < MethodDefinition
|
10
|
+
build_with MethodBuilder::BlockMethodBuilder
|
11
|
+
|
10
12
|
# @param name [String,Symbol] name of the method
|
11
13
|
# @param block [Proc] block with code to be added as method
|
12
14
|
# @param options [Hash] Options of construction
|
@@ -7,6 +7,8 @@ class Sinclair
|
|
7
7
|
#
|
8
8
|
# Define a call of method to e done within the class
|
9
9
|
class CallDefinition < MethodDefinition
|
10
|
+
build_with MethodBuilder::CallMethodBuilder
|
11
|
+
|
10
12
|
# @param method_name [Symbol] method to be called
|
11
13
|
# @param arguments [Array<Symbol,String>] parameters to be passed as
|
12
14
|
# arguments to the call
|
@@ -18,35 +20,30 @@ class Sinclair
|
|
18
20
|
default_value :block?, false
|
19
21
|
default_value :string?, false
|
20
22
|
|
21
|
-
#
|
22
|
-
# @return [String]
|
23
|
-
def code_string
|
24
|
-
"#{name} :#{arguments.join(', :')}"
|
25
|
-
end
|
26
|
-
|
27
|
-
# String to be executed within the class running code to change the class itself
|
23
|
+
# Block to be evaluated by the class when adding methods
|
28
24
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
25
|
+
# The block will be a call from +method_name+ passing +arguments+
|
26
|
+
# as arguments
|
27
|
+
# @return [Proc]
|
28
|
+
def code_block
|
29
|
+
method_name = name
|
30
|
+
args = arguments
|
31
|
+
|
32
|
+
proc do
|
33
|
+
send(method_name, *args)
|
34
|
+
end
|
37
35
|
end
|
38
36
|
|
39
37
|
private
|
40
38
|
|
41
39
|
attr_reader :arguments
|
42
|
-
|
43
40
|
# @method arguments
|
44
41
|
# @api private
|
45
42
|
# @private
|
46
43
|
#
|
47
|
-
#
|
44
|
+
# Arguments to be passed when calling the method inside the block
|
48
45
|
#
|
49
|
-
# @return [Array<
|
46
|
+
# @return [Array<Object>]
|
50
47
|
end
|
51
48
|
end
|
52
49
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class MethodDefinition
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Builder a string of parameters
|
9
|
+
#
|
10
|
+
# This is used when creating the string for a method defined
|
11
|
+
# using a string definition
|
12
|
+
#
|
13
|
+
# @see StringDefinition
|
14
|
+
class ParameterBuilder
|
15
|
+
# Builds a string representing method parameters
|
16
|
+
#
|
17
|
+
# @overload from(parameters, named_parameters)
|
18
|
+
# @param parameters [Array<Object>] List of parameters.
|
19
|
+
# @param named_parameters [Array<Object>] List of named parameters
|
20
|
+
#
|
21
|
+
# The list of +parameters+/+named_parameters+ is formed by an
|
22
|
+
# array of +Symbol+ representing required parameters
|
23
|
+
# and +Hash+ representing parameters with default values
|
24
|
+
#
|
25
|
+
# @return [String]
|
26
|
+
def self.from(*args)
|
27
|
+
new(*args).to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
private_class_method :new
|
31
|
+
|
32
|
+
# @param parameters [Array<Object>] List of parameters.
|
33
|
+
# @param named_parameters [Array<Object>] List of named parameters
|
34
|
+
def initialize(parameters, named_parameters)
|
35
|
+
@parameters = parameters
|
36
|
+
@named_parameters = named_parameters
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the parameters string
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def to_s
|
43
|
+
return '' if empty_parameters?
|
44
|
+
|
45
|
+
"(#{parameters_string})"
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
attr_reader :parameters, :named_parameters
|
51
|
+
|
52
|
+
# @!method parameters
|
53
|
+
# @api private
|
54
|
+
# @private
|
55
|
+
#
|
56
|
+
# List of parameters
|
57
|
+
#
|
58
|
+
# @return [Array<Object>]
|
59
|
+
|
60
|
+
# @!method named_parameters
|
61
|
+
# @api private
|
62
|
+
# @private
|
63
|
+
#
|
64
|
+
# List of named parameters
|
65
|
+
#
|
66
|
+
# @return [Array<Object>]
|
67
|
+
|
68
|
+
# @private
|
69
|
+
# Flag if any kind of parameters have not been provided
|
70
|
+
#
|
71
|
+
# @return [TrueClass,FalseClass]
|
72
|
+
def empty_parameters?
|
73
|
+
!parameters.present? && !named_parameters.present?
|
74
|
+
end
|
75
|
+
|
76
|
+
# String of parameters witout ()
|
77
|
+
#
|
78
|
+
# This will join all individual parameters strings by +,+
|
79
|
+
#
|
80
|
+
# @return [String]
|
81
|
+
def parameters_string
|
82
|
+
(
|
83
|
+
ParameterHelper.parameters_from(parameters) +
|
84
|
+
ParameterHelper.parameters_from(named_parameters, named: true)
|
85
|
+
).join(', ')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Sinclair
|
4
|
+
class MethodDefinition
|
5
|
+
# @api private
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Helper containing helepr methods for remapping parameters
|
9
|
+
#
|
10
|
+
# @see ParameterBuilder
|
11
|
+
class ParameterHelper
|
12
|
+
# Returns a list of strings of parameters
|
13
|
+
#
|
14
|
+
# @overload parameters_from(parameters_list, named: false)
|
15
|
+
# @param parameters_list [Array<Object>] list of parameters and defaults
|
16
|
+
# @param named [TrueClass,FalseClass] Flag informing if the parameters are
|
17
|
+
# named parameters
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
def self.parameters_from(*args, **opts)
|
21
|
+
new(*args, **opts).strings
|
22
|
+
end
|
23
|
+
|
24
|
+
private_class_method :new
|
25
|
+
|
26
|
+
# @param parameters_list [Array<Object>] list of parameters and defaults
|
27
|
+
# @param named [TrueClass,FalseClass] Flag informing if the parameters are
|
28
|
+
# named parameters
|
29
|
+
def initialize(parameters_list, named: false)
|
30
|
+
@parameters_list = parameters_list
|
31
|
+
@named = named
|
32
|
+
end
|
33
|
+
|
34
|
+
# All parameters converted into strings
|
35
|
+
#
|
36
|
+
# The strings are ready to be pushed into a method definition
|
37
|
+
# and joined by +,+
|
38
|
+
#
|
39
|
+
# @return [Array<String>]
|
40
|
+
def strings
|
41
|
+
return [] unless parameters_list
|
42
|
+
|
43
|
+
parameters_strings + defaults_strings
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :parameters_list, :named
|
49
|
+
alias named? named
|
50
|
+
|
51
|
+
# @!method parameters_list
|
52
|
+
# @api private
|
53
|
+
# @private
|
54
|
+
#
|
55
|
+
# List of parameters and parameters with defaults
|
56
|
+
#
|
57
|
+
# @return [Array<Object>]
|
58
|
+
|
59
|
+
# @!method named
|
60
|
+
# @api private
|
61
|
+
# @private
|
62
|
+
#
|
63
|
+
# Flag informing if the parameters are named parameters
|
64
|
+
#
|
65
|
+
# @return [TrueClass,FalseClass]
|
66
|
+
|
67
|
+
# @!method named?
|
68
|
+
# @api private
|
69
|
+
# @private
|
70
|
+
#
|
71
|
+
# Flag informing if the parameters are named parameters
|
72
|
+
#
|
73
|
+
# @return [TrueClass,FalseClass]
|
74
|
+
|
75
|
+
# Parameters without defaults
|
76
|
+
#
|
77
|
+
# These are filtered out from {#parameters_list} where they are not
|
78
|
+
# of type +Hash+
|
79
|
+
#
|
80
|
+
# @return [Array<Symbol>]
|
81
|
+
def parameters
|
82
|
+
parameters_list.reject do |param|
|
83
|
+
param.is_a?(Hash)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Hash representing all parameters with default values
|
88
|
+
#
|
89
|
+
# These are filtered out from {#parameters_list} where they are
|
90
|
+
# of type +Hash+ and merged into a single hash
|
91
|
+
#
|
92
|
+
# @return [Hash]
|
93
|
+
def defaults
|
94
|
+
parameters_list.select do |param|
|
95
|
+
param.is_a?(Hash)
|
96
|
+
end.reduce(&:merge) || {}
|
97
|
+
end
|
98
|
+
|
99
|
+
# Parameters without default converted to final string
|
100
|
+
#
|
101
|
+
# {#extra} is added so that for normal parameters the parameter is returned
|
102
|
+
# and for named parameter +:+ is added
|
103
|
+
#
|
104
|
+
# @return [Array<String>]
|
105
|
+
def parameters_strings
|
106
|
+
return parameters.map(&:to_s) unless named?
|
107
|
+
|
108
|
+
parameters.map do |param|
|
109
|
+
"#{param}:"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Strings representing all parameters with default value
|
114
|
+
#
|
115
|
+
# @return [Array<String>]
|
116
|
+
def defaults_strings
|
117
|
+
joinner = named? ? ': ' : ' = '
|
118
|
+
defaults.map do |key, value|
|
119
|
+
"#{key}#{joinner}#{value}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -7,6 +7,8 @@ class Sinclair
|
|
7
7
|
#
|
8
8
|
# Define an instance method from string
|
9
9
|
class StringDefinition < MethodDefinition
|
10
|
+
build_with MethodBuilder::StringMethodBuilder
|
11
|
+
|
10
12
|
# @param name [String,Symbol] name of the method
|
11
13
|
# @param code [String] code to be evaluated as method
|
12
14
|
# @param options [Hash] Options of construction
|
@@ -20,6 +22,30 @@ class Sinclair
|
|
20
22
|
default_value :block?, false
|
21
23
|
default_value :string?, true
|
22
24
|
|
25
|
+
# string with the code to be defined
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
def code_definition
|
29
|
+
<<-CODE
|
30
|
+
def #{name}#{parameters_string}
|
31
|
+
#{code_line}
|
32
|
+
end
|
33
|
+
CODE
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# @private
|
39
|
+
# String for parameters
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def parameters_string
|
43
|
+
ParameterBuilder.from(
|
44
|
+
options_object.parameters, options_object.named_parameters
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @private
|
23
49
|
# codeline to be run inside the code
|
24
50
|
#
|
25
51
|
# @return [String]
|
@@ -27,8 +53,6 @@ class Sinclair
|
|
27
53
|
cached? ? code_with_cache : code
|
28
54
|
end
|
29
55
|
|
30
|
-
private
|
31
|
-
|
32
56
|
# @method code
|
33
57
|
# @private
|
34
58
|
#
|
@@ -10,8 +10,10 @@ class Sinclair
|
|
10
10
|
|
11
11
|
autoload :BlockHelper, 'sinclair/method_definition/block_helper'
|
12
12
|
autoload :BlockDefinition, 'sinclair/method_definition/block_definition'
|
13
|
-
autoload :StringDefinition, 'sinclair/method_definition/string_definition'
|
14
13
|
autoload :CallDefinition, 'sinclair/method_definition/call_definition'
|
14
|
+
autoload :StringDefinition, 'sinclair/method_definition/string_definition'
|
15
|
+
autoload :ParameterBuilder, 'sinclair/method_definition/parameter_builder'
|
16
|
+
autoload :ParameterHelper, 'sinclair/method_definition/parameter_helper'
|
15
17
|
|
16
18
|
# @method name
|
17
19
|
#
|
@@ -59,13 +61,47 @@ class Sinclair
|
|
59
61
|
# The creation is based on type which will be used to infer
|
60
62
|
# which subclass of {Sinclair::MethodDefinition} to be used
|
61
63
|
#
|
64
|
+
# If type is +nil+ then call is delegated to {.from} which will infer the type
|
65
|
+
# from the arguments
|
66
|
+
#
|
62
67
|
# @param type [Symbol] the method definition type
|
63
68
|
#
|
64
69
|
# @return [Sinclair::MethodDefinition] an instance of a subclass
|
65
70
|
def for(type, *args, **options, &block)
|
71
|
+
return from(*args, **options, &block) unless type
|
72
|
+
|
66
73
|
klass = const_get("#{type}_definition".camelize)
|
67
74
|
klass.new(*args, **options, &block)
|
68
75
|
end
|
76
|
+
|
77
|
+
# Defines builder for a definition class
|
78
|
+
#
|
79
|
+
# @param builder_class [Class<MethodBuilder>]
|
80
|
+
#
|
81
|
+
# @return [Symbol] constant +:build+
|
82
|
+
#
|
83
|
+
# @!macro build_with
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
# @!method build(klass, type)
|
87
|
+
#
|
88
|
+
# Builds the method defined
|
89
|
+
#
|
90
|
+
# The method is built using {$1}
|
91
|
+
#
|
92
|
+
# @param klass [Class] The class where the method will be built
|
93
|
+
# @param type [Symbol] type of method to be built
|
94
|
+
# - {MethodBuilder::CLASS_METHOD} : A class method will be built
|
95
|
+
# - {MethodBuilder::INSTANCE_METHOD} : An instance method will be built
|
96
|
+
#
|
97
|
+
# @see $1#build
|
98
|
+
#
|
99
|
+
# @return [Symbol] the name of the method built
|
100
|
+
def build_with(builder_class)
|
101
|
+
define_method(:build) do |klass, type|
|
102
|
+
builder_class.build(klass, self, type: type)
|
103
|
+
end
|
104
|
+
end
|
69
105
|
end
|
70
106
|
|
71
107
|
# @param name [String,Symbol] name of the method
|
@@ -87,10 +123,13 @@ class Sinclair
|
|
87
123
|
#
|
88
124
|
# @example (see MethodDefinition::StringDefinition#build)
|
89
125
|
# @example (see MethodDefinition::BlockDefinition#build)
|
126
|
+
# @example (see MethodDefinition::CallDefinition#build)
|
90
127
|
#
|
91
128
|
# @return [Symbol] name of the created method
|
92
|
-
|
93
|
-
|
129
|
+
#
|
130
|
+
# @raise NotImplementedError
|
131
|
+
def build(_klass, _type)
|
132
|
+
raise NotImplementedError, 'Build is implemented in subclasses. ' \
|
94
133
|
"Use #{self.class}.from to initialize a proper object"
|
95
134
|
end
|
96
135
|
|