sinclair 1.10.0 → 1.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/README.md +414 -324
  4. data/config/check_specs.yml +3 -4
  5. data/config/yardstick.yml +2 -0
  6. data/lib/sinclair/matchers/add_class_method.rb +0 -1
  7. data/lib/sinclair/method_builder/base.rb +17 -2
  8. data/lib/sinclair/method_builder/call_method_builder.rb +21 -21
  9. data/lib/sinclair/method_builder.rb +5 -20
  10. data/lib/sinclair/method_definition/block_definition.rb +2 -0
  11. data/lib/sinclair/method_definition/call_definition.rb +15 -18
  12. data/lib/sinclair/method_definition/string_definition.rb +2 -0
  13. data/lib/sinclair/method_definition.rb +41 -3
  14. data/lib/sinclair/method_definitions.rb +20 -22
  15. data/lib/sinclair/version.rb +1 -1
  16. data/lib/sinclair.rb +149 -62
  17. data/spec/integration/readme/sinclair/types_of_definition_spec.rb +47 -0
  18. data/spec/integration/yard/sinclair/add_class_method_spec.rb +51 -0
  19. data/spec/integration/yard/sinclair/add_method_spec.rb +60 -0
  20. data/spec/integration/yard/sinclair/eval_and_add_method_spec.rb +26 -0
  21. data/spec/integration/yard/sinclair_spec.rb +0 -83
  22. data/spec/lib/sinclair/method_builder/base_spec.rb +15 -0
  23. data/spec/lib/sinclair/method_definition/call_definition_spec.rb +14 -17
  24. data/spec/lib/sinclair/method_definition_spec.rb +67 -2
  25. data/spec/lib/sinclair/method_definitions_spec.rb +15 -16
  26. data/spec/lib/sinclair_spec.rb +6 -160
  27. data/spec/support/models/dummy_builder.rb +4 -1
  28. data/spec/support/models/dummy_class_builder.rb +3 -0
  29. data/spec/support/models/person.rb +1 -1
  30. data/spec/support/shared_examples/sinclair.rb +112 -0
  31. metadata +8 -2
@@ -1,10 +1,9 @@
1
1
  ignore:
2
2
  - lib/sinclair/comparable/class_methods.rb
3
+ - lib/sinclair/exception.rb
3
4
  - lib/sinclair/matchers/add_method_to.rb
4
5
  - lib/sinclair/matchers/add_method.rb
5
- - lib/sinclair/version.rb
6
- - lib/sinclair/method_builder/base.rb
7
- - lib/sinclair/exception.rb
8
- - lib/sinclair/matchers/method_to.rb
9
6
  - lib/sinclair/matchers/base.rb
7
+ - lib/sinclair/matchers/method_to.rb
10
8
  - lib/sinclair/matchers/change_method_on.rb
9
+ - 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
@@ -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 NotImplementedYet
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
@@ -9,41 +9,41 @@ 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
- klass.module_eval(code_line, __FILE__, __LINE__ + 1)
19
+ evaluating_class.module_eval(&code_block)
15
20
  end
16
21
 
17
22
  private
18
23
 
24
+ delegate :code_block, to: :definition
25
+ # @method code_block
19
26
  # @api private
20
27
  # @private
21
28
  #
22
- # String to be evaluated when building the method
29
+ # Code block to be evaluated by the class
23
30
  #
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
31
+ # @return [Proc]
29
32
 
30
- delegate :code_string, :class_code_string, to: :definition
31
-
32
- # @method code_string
33
- # @private
34
- # @api private
33
+ # Returns the klass where the proc block will be evaluated
35
34
  #
36
- # Delegated from {MethodDefinition::CallDefinition}
35
+ # For instance type, the class itself is returned
37
36
  #
38
- # @see MethodDefinition::CallDefinition#code_string
39
- # @return [String]
40
-
41
- # @method class_code_string
42
- # @private
43
- # @api private
37
+ # For adding class methods, the superclass is returned
44
38
  #
45
- # @see MethodDefinition::CallDefinition#class_code_string
46
- # @return [String]
39
+ # @return [Class]
40
+ def evaluating_class
41
+ return klass if instance?
42
+
43
+ class << klass
44
+ return self
45
+ end
46
+ end
47
47
  end
48
48
  end
49
49
  end
@@ -9,7 +9,8 @@ class Sinclair
9
9
  autoload :Base, 'sinclair/method_builder/base'
10
10
  autoload :StringMethodBuilder, 'sinclair/method_builder/string_method_builder'
11
11
  autoload :BlockMethodBuilder, 'sinclair/method_builder/block_method_builder'
12
- autoload :CallMethodBuilder, 'sinclair/method_builder/call_method_builder'
12
+
13
+ autoload :CallMethodBuilder, 'sinclair/method_builder/call_method_builder'
13
14
 
14
15
  CLASS_METHOD = :class
15
16
  INSTANCE_METHOD = :instance
@@ -24,11 +25,13 @@ class Sinclair
24
25
  # @param definitions [MethodDefinitions] all methods
25
26
  # definitions to be built
26
27
  # @param type [Symbol] type of method to be built
28
+ # - {CLASS_METHOD} : A class method will be built
29
+ # - {INSTANCE_METHOD} : An instance method will be built
27
30
  #
28
31
  # @return [MethodDefinitions]
29
32
  def build_methods(definitions, type)
30
33
  definitions.each do |definition|
31
- build_from_definition(definition, type)
34
+ definition.build(klass, type)
32
35
  end
33
36
  end
34
37
 
@@ -42,23 +45,5 @@ class Sinclair
42
45
  # class to receive the method
43
46
  #
44
47
  # @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
48
  end
64
49
  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
- # String to be executed within the class
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
- # @see code_string
30
- # @return [String]
31
- def class_code_string
32
- <<-CODE
33
- class << self
34
- #{code_string}
35
- end
36
- CODE
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
- # parameters to be passed as arguments to the call
44
+ # Arguments to be passed when calling the method inside the block
48
45
  #
49
- # @return [Array<Symbol,String>]
46
+ # @return [Array<Object>]
50
47
  end
51
48
  end
52
49
  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
@@ -11,7 +11,8 @@ class Sinclair
11
11
  autoload :BlockHelper, 'sinclair/method_definition/block_helper'
12
12
  autoload :BlockDefinition, 'sinclair/method_definition/block_definition'
13
13
  autoload :StringDefinition, 'sinclair/method_definition/string_definition'
14
- autoload :CallDefinition, 'sinclair/method_definition/call_definition'
14
+
15
+ autoload :CallDefinition, 'sinclair/method_definition/call_definition'
15
16
 
16
17
  # @method name
17
18
  #
@@ -59,13 +60,47 @@ class Sinclair
59
60
  # The creation is based on type which will be used to infer
60
61
  # which subclass of {Sinclair::MethodDefinition} to be used
61
62
  #
63
+ # If type is +nil+ then call is delegated to {.from} which will infer the type
64
+ # from the arguments
65
+ #
62
66
  # @param type [Symbol] the method definition type
63
67
  #
64
68
  # @return [Sinclair::MethodDefinition] an instance of a subclass
65
69
  def for(type, *args, **options, &block)
70
+ return from(*args, **options, &block) unless type
71
+
66
72
  klass = const_get("#{type}_definition".camelize)
67
73
  klass.new(*args, **options, &block)
68
74
  end
75
+
76
+ # Defines builder for a definition class
77
+ #
78
+ # @param builder_class [Class<MethodBuilder>]
79
+ #
80
+ # @return [Symbol] constant +:build+
81
+ #
82
+ # @!macro build_with
83
+ # @api private
84
+ #
85
+ # @!method build(klass, type)
86
+ #
87
+ # Builds the method defined
88
+ #
89
+ # The method is built using {$1}
90
+ #
91
+ # @param klass [Class] The class where the method will be built
92
+ # @param type [Symbol] type of method to be built
93
+ # - {MethodBuilder::CLASS_METHOD} : A class method will be built
94
+ # - {MethodBuilder::INSTANCE_METHOD} : An instance method will be built
95
+ #
96
+ # @see $1#build
97
+ #
98
+ # @return [Symbol] the name of the method built
99
+ def build_with(builder_class)
100
+ define_method(:build) do |klass, type|
101
+ builder_class.build(klass, self, type: type)
102
+ end
103
+ end
69
104
  end
70
105
 
71
106
  # @param name [String,Symbol] name of the method
@@ -87,10 +122,13 @@ class Sinclair
87
122
  #
88
123
  # @example (see MethodDefinition::StringDefinition#build)
89
124
  # @example (see MethodDefinition::BlockDefinition#build)
125
+ # @example (see MethodDefinition::CallDefinition#build)
90
126
  #
91
127
  # @return [Symbol] name of the created method
92
- def build(_klass)
93
- raise 'Build is implemented in subclasses. ' \
128
+ #
129
+ # @raise NotImplementedError
130
+ def build(_klass, _type)
131
+ raise NotImplementedError, 'Build is implemented in subclasses. ' \
94
132
  "Use #{self.class}.from to initialize a proper object"
95
133
  end
96
134
 
@@ -12,37 +12,35 @@ class Sinclair
12
12
  #
13
13
  # The type is decided based in the arguments
14
14
  #
15
- # @param name [String,Symbol] method name
16
- # @param options [Hash] Options of construction
17
- # @option options cached [Boolean] Flag telling to create
18
- # a method with cache
19
- #
20
15
  # @overload add(definition_class, name, code = nil, **options)
16
+ # @param name [String,Symbol] method name
21
17
  # @param code [String] code to be evaluated when the method is ran
18
+ # @param options [Hash] Options of construction
19
+ # @option options cached [Boolean] Flag telling to create
20
+ # a method with cache
22
21
  #
23
22
  # @overload add(definition_class, name, **options, &block)
23
+ # @param name [String,Symbol] method name
24
+ # @param options [Hash] Options of construction
25
+ # @option options cached [Boolean] Flag telling to create
26
+ # a method with cache
24
27
  # @param block [Proc] block to be ran as method
25
28
  #
26
- # @return [Array<MethodDefinition>]
27
- def add(name, code = nil, **options, &block)
28
- definitions << MethodDefinition.from(name, code, **options, &block)
29
- end
30
-
31
- # Builds and adds new definition
32
- #
33
- # The type is decided based on the argument +type+
29
+ # @overload add(type, *args, **options, &block)
30
+ # @param type [Symbol] type of definition
31
+ # - :string -> {MethodDefinition::StringDefinition}
32
+ # - :block -> {MethodDefinition::BlockDefinition}
33
+ # - :call -> {MethodDefinition::CallDefinition}
34
+ # @param options [Hash] Options of construction
35
+ # @option options cached [Boolean] Flag telling to create
36
+ # a method with cache
37
+ # @param block [Proc] block to be ran as method
34
38
  #
35
- # @param type [Symbol] type of definition
36
- # - :string -> {MethodDefinition::StringDefinition}
37
- # - :block -> {MethodDefinition::BlockDefinition}
38
- # - :call -> {MethodDefinition::CallDefinition}
39
- # @param options [Hash] Options of construction
40
- # @option options cached [Boolean] Flag telling to create
41
- # a method with cache
42
- # @param block [Proc] block to be ran as method
39
+ # @see MethodDefinition.for
40
+ # @see MethodDefinition.from
43
41
  #
44
42
  # @return [Array<MethodDefinition>]
45
- def add_definition(type, *args, **options, &block)
43
+ def add(*args, type: nil, **options, &block)
46
44
  definitions << MethodDefinition.for(type, *args, **options, &block)
47
45
  end
48
46
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Sinclair
4
- VERSION = '1.10.0'
4
+ VERSION = '1.11.0'
5
5
  end
data/lib/sinclair.rb CHANGED
@@ -179,107 +179,193 @@ class Sinclair
179
179
  end
180
180
 
181
181
  # Add a method to the method list to be created on klass instances
182
- #
183
- # @param name [String,Symbol] name of the method to be added
184
- # @param options [Hash] Options of construction
185
- # @option options cached [Boolean] Flag telling to create
186
- # a method with cache
182
+ # @see MethodDefinitions#add
187
183
  #
188
184
  # @overload add_method(name, code, **options)
185
+ # @param name [String,Symbol] name of the method to be added
189
186
  # @param code [String] code to be evaluated when the method is ran
187
+ # @param options [Hash] Options of construction
188
+ # @option options cached [Boolean] Flag telling to create
189
+ # a method with cache
190
+ # @see MethodDefinition::StringDefinition
191
+ #
192
+ # @example Using string code to add a string defined method
193
+ # class Person
194
+ # attr_accessor :first_name, :last_name
195
+ #
196
+ # def initialize(first_name, last_name)
197
+ # @first_name = first_name
198
+ # @last_name = last_name
199
+ # end
200
+ # end
201
+ #
202
+ # builder = Sinclair.new(Person)
203
+ # builder.add_method(:full_name, '[first_name, last_name].join(" ")')
204
+ # builder.build
205
+ #
206
+ # Person.new('john', 'wick').full_name # returns 'john wick'
190
207
  #
191
208
  # @overload add_method(name, **options, &block)
209
+ # @param name [String,Symbol] name of the method to be added
192
210
  # @param block [Proc] block to be ran as method
211
+ # @param options [Hash] Options of construction
212
+ # @option options cached [Boolean] Flag telling to create
213
+ # a method with cache
214
+ # @see MethodDefinition::BlockDefinition
215
+ #
216
+ # @example Using block to add a block method
217
+ # class Person
218
+ # attr_accessor :first_name, :last_name
219
+ #
220
+ # def initialize(first_name, last_name)
221
+ # @first_name = first_name
222
+ # @last_name = last_name
223
+ # end
224
+ # end
193
225
  #
194
- # @example Using string code
195
- # class Person
196
- # attr_reader :first_name, :last_name
197
- #
198
- # def initialize(first_name, last_name)
199
- # @first_name = first_name
200
- # @last_name = last_name
226
+ # builder = Sinclair.new(Person)
227
+ # builder.add_method(:bond_name) { "#{last_name}, #{first_name} #{last_name}" }
228
+ # builder.build
229
+ #
230
+ # Person.new('john', 'wick').bond_name # returns 'wick, john wick'
231
+ #
232
+ # @overload add_method(*args, type:, **options, &block)
233
+ # @param args [Array<Object>] arguments to be passed to the definition
234
+ # @param type [Symbol] type of method definition
235
+ # @param block [Proc] block to be ran as method when type is block
236
+ # @param options [Hash] Options of construction
237
+ # @option options cached [Boolean] Flag telling to create
238
+ # a method with cache
239
+ # @see MethodDefinition::BlockDefinition
240
+ # @see MethodDefinition::StringDefinition
241
+ # @see MethodDefinition::CallDefinition
242
+ #
243
+ # @example Passing type block
244
+ # class Person
245
+ # attr_accessor :first_name, :last_name
246
+ #
247
+ # def initialize(first_name, last_name)
248
+ # @first_name = first_name
249
+ # @last_name = last_name
250
+ # end
201
251
  # end
202
- # end
203
252
  #
204
- # builder = Sinclair.new(Person)
205
- # builder.add_method(:full_name, '[first_name, last_name].join(" ")')
206
- # builder.build
253
+ # builder = Sinclair.new(Person)
254
+ # builder.add_method(:bond_name, type: :block, cached: true) do
255
+ # "{last_name}, #{first_name} #{last_name}"
256
+ # end
257
+ # builder.build
207
258
  #
208
- # Person.new('john', 'wick').full_name # returns 'john wick'
259
+ # person.Person.new('john', 'wick')
209
260
  #
210
- # @example Using block
211
- # class Person
212
- # attr_reader :first_name, :last_name
261
+ # person.bond_name # returns 'wick, john wick'
262
+ # person.first_name = 'Johny'
263
+ # person.bond_name # returns 'wick, john wick'
213
264
  #
214
- # def initialize(first_name, last_name)
215
- # @first_name = first_name
216
- # @last_name = last_name
265
+ # @example Passing type call
266
+ # class Person
217
267
  # end
218
- # end
219
268
  #
220
- # builder = Sinclair.new(Person)
221
- # builder.add_method(:full_name, '[first_name, last_name].join(" ")')
222
- # builder.add_method(:bond_name) { "#{last_name}, #{full_name}" }
223
- # builder.build
269
+ # builder = Sinclair.new(Person)
270
+ # builder.add_method(:attr_accessor, :bond_name, type: :call)
271
+ # builder.build
224
272
  #
225
- # Person.new('john', 'wick').bond_name # returns 'wick, john wick'
226
- # @return [Array<MethodDefinition>]
227
- def add_method(name, code = nil, **options, &block)
228
- definitions.add(
229
- name, code, **options, &block
230
- )
273
+ # person.bond_name = 'Bond, James Bond'
274
+ # person.bond_name # returns 'Bond, James Bond'
275
+ #
276
+ # @return [Array<MethodDefinition>] the list of all currently defined instance methods
277
+ def add_method(*args, type: nil, **options, &block)
278
+ definitions.add(*args, type: type, **options, &block)
231
279
  end
232
280
 
233
281
  # Add a method to the method list to be created on klass
234
- #
235
- # @param name [String,Symbol] name of the method to be added
236
- # @param options [Hash] Options of construction
237
- # @option options cached [Boolean] Flag telling to create
238
- # a method with cache
282
+ # @see MethodDefinitions#add
239
283
  #
240
284
  # @overload add_class_method(name, code, **options)
285
+ # @param name [String,Symbol] name of the method to be added
241
286
  # @param code [String] code to be evaluated when the method is ran
287
+ # @param options [Hash] Options of construction
288
+ # @option options cached [Boolean] Flag telling to create
289
+ # a method with cache
290
+ #
291
+ # @example Adding a method by String
292
+ # class EnvFetcher
293
+ # end
294
+ #
295
+ # builder = Sinclair.new(EnvFetcher)
296
+ #
297
+ # builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
298
+ # builder.build
299
+ #
300
+ # ENV['HOSTNAME'] = 'myhost'
301
+ #
302
+ # EnvFetcher.hostname # returns 'myhost'
242
303
  #
243
304
  # @overload add_class_method(name, **options, &block)
305
+ # @param name [String,Symbol] name of the method to be added
244
306
  # @param block [Proc] block to be ran as method
307
+ # @param options [Hash] Options of construction
308
+ # @option options cached [Boolean] Flag telling to create
309
+ # a method with cache
245
310
  #
246
- # @example
247
- # class EnvFetcher
248
- # end
311
+ # @example Adding a method by Block
312
+ # class EnvFetcher
313
+ # end
249
314
  #
250
- # builder = Sinclair.new(EnvFetcher)
315
+ # builder = Sinclair.new(EnvFetcher)
251
316
  #
252
- # builder.add_class_method(:hostname, 'ENV["HOSTNAME"]')
253
- # builder.build
317
+ # builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
318
+ # builder.build
254
319
  #
255
- # ENV['HOSTNAME'] = 'myhost'
320
+ # ENV['TIMEOUT'] = '300'
256
321
  #
257
- # env_fetcher.hostname # returns 'myhost'
322
+ # EnvFetcher.timeout # returns '300'
258
323
  #
259
- # @example
260
- # class EnvFetcher
261
- # end
324
+ # @overload add_class_method(*args, type: **options, &block)
325
+ # @param args [Array<Object>] arguments to be passed to the definition
326
+ # @param type [Symbol] type of method definition
327
+ # @param block [Proc] block to be ran as method when type is block
328
+ # @param options [Hash] Options of construction
329
+ # @option options cached [Boolean] Flag telling to create
330
+ # a method with cache
331
+ # @see MethodDefinition::BlockDefinition
332
+ # @see MethodDefinition::StringDefinition
333
+ # @see MethodDefinition::CallDefinition
262
334
  #
263
- # builder = Sinclair.new(EnvFetcher)
335
+ # @example Passing type block
336
+ # class EnvFetcher
337
+ # end
264
338
  #
265
- # builder.add_class_method(:timeout) { ENV['TIMEOUT'] }
266
- # builder.build
339
+ # builder = Sinclair.new(EnvFetcher)
267
340
  #
268
- # ENV['TIMEOUT'] = '300'
341
+ # builder.add_class_method(:timeout, type: :block) { ENV['TIMEOUT'] }
342
+ # builder.build
269
343
  #
270
- # env_fetcher.timeout # returns '300'
344
+ # ENV['TIMEOUT'] = '300'
271
345
  #
272
- # @return [Array<MethodDefinition>]
273
- def add_class_method(name, code = nil, **options, &block)
274
- class_definitions.add(
275
- name, code, **options, &block
276
- )
346
+ # EnvFetcher.timeout # returns '300'
347
+ #
348
+ # @example Passing type call
349
+ # class EnvFetcher
350
+ # end
351
+ #
352
+ # builder = Sinclair.new(EnvFetcher)
353
+ #
354
+ # builder.add_class_method(:attr_accessor, :timeout, type: :call)
355
+ # builder.build
356
+ #
357
+ # EnvFetcher.timeout = 10
358
+ #
359
+ # env_fetcher.timeout # returns '10'
360
+ #
361
+ # @return [Array<MethodDefinition>] the list of all currently defined class methods
362
+ def add_class_method(*args, type: nil, **options, &block)
363
+ class_definitions.add(*args, type: type, **options, &block)
277
364
  end
278
365
 
279
366
  # Evaluetes a block which will result in a String, the method code
280
367
  #
281
368
  # @example Building a initial value class method
282
- #
283
369
  # module InitialValuer
284
370
  # extend ActiveSupport::Concern
285
371
  #
@@ -301,6 +387,7 @@ class Sinclair
301
387
  # end
302
388
  #
303
389
  # object = MyClass.new
390
+ #
304
391
  # object.age # 20
305
392
  # object.age = 30
306
393
  # object.age # 30
@@ -345,7 +432,7 @@ class Sinclair
345
432
  # end
346
433
  #
347
434
  # Purchase.new(2.3, 5).total_price # returns 11.5
348
- # @return [Array<MethodDefinition>]
435
+ # @return [Array<MethodDefinition>] the list of all currently defined instance methods
349
436
  def eval_and_add_method(name, &block)
350
437
  add_method(name, instance_eval(&block))
351
438
  end