verbalize 0.1.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f008ed2bf42154162943268c8c10d75ca09ca586
4
- data.tar.gz: fdc71af9ad1a73d1f49ce85ec2bbc94a4870c1ac
3
+ metadata.gz: a7744e15c5aa0fc769954ed09eee485ae48e09c7
4
+ data.tar.gz: 5e3399e68683e2c832867b15d7dd7ce83fccdddf
5
5
  SHA512:
6
- metadata.gz: 85ba485dee2564adb6cb8a3d3ca073a05f7cf27f65ef94599664575e64ae10d2d009c3d0bc404e1dc332e88f95c778f8e2bf7ff311cc314e3feace3fd0728f69
7
- data.tar.gz: 5cda9a96c5e0162fd9f3f16645f85dcd8cefb6a1b8c0db49091b7ce4aff594eeedc2e28ba1fa9f229e1589f7d8fe77beed2a992cf604ed00cd920ef47d143083
6
+ metadata.gz: 8dfcf51ef06b9d77c5b7139339511e7d0800d11294f065a37cfcf412a805b3e67dcbd420672658f9797790294dfb19097fc4c70fccd9b8c5ec2e02e1f1ab96e4
7
+ data.tar.gz: bf914ab418dc0266d1b89e794c275258f6b406481a9e44b67797eef035c2ee31aaa6554a22bad47a5f7a371f6a834ee76e4dc1b380e799376a2dcb2b3d5320c2
data/README.md CHANGED
@@ -30,7 +30,7 @@ value # => 42
30
30
  class Add
31
31
  include Verbalize
32
32
 
33
- input :a, :b
33
+ input optional: [:a, :b]
34
34
 
35
35
  def call
36
36
  a + b
@@ -48,7 +48,7 @@ class Add
48
48
  end
49
49
 
50
50
  Add.call # => [:ok, 42]
51
- Add.call(a: 42, b: 0) # => [:ok, 42]
51
+ Add.call(a: 660, b: 6) # => [:ok, 666]
52
52
  ```
53
53
 
54
54
  ```ruby
@@ -69,6 +69,11 @@ result.failed? # => true
69
69
 
70
70
  ## Comparison/Benchmark
71
71
  ```ruby
72
+ require 'verbalize'
73
+ require 'actionizer'
74
+ require 'interactor'
75
+ require 'benchmark/ips'
76
+
72
77
  class RubyAdd
73
78
  def self.call(a:, b:)
74
79
  new(a: a, b: b).call
@@ -87,9 +92,7 @@ class RubyAdd
87
92
 
88
93
  attr_reader :a, :b
89
94
  end
90
- ```
91
95
 
92
- ```ruby
93
96
  class VerbalizeAdd
94
97
  include Verbalize
95
98
 
@@ -99,9 +102,7 @@ class VerbalizeAdd
99
102
  a + b
100
103
  end
101
104
  end
102
- ```
103
105
 
104
- ```ruby
105
106
  class ActionizerAdd
106
107
  include Actionizer
107
108
 
@@ -109,9 +110,7 @@ class ActionizerAdd
109
110
  output.sum = input.a + input.b
110
111
  end
111
112
  end
112
- ```
113
113
 
114
- ```ruby
115
114
  class InteractorAdd
116
115
  include Interactor
117
116
 
@@ -119,14 +118,10 @@ class InteractorAdd
119
118
  context.sum = context.a + context.b
120
119
  end
121
120
  end
122
- ```
123
-
124
- ```ruby
125
- require 'benchmark/ips'
126
121
 
127
122
  Benchmark.ips do |x|
128
123
  x.report('Ruby') { RubyAdd.call(a: 1, b: 2) }
129
- x.report('Verbal') { VerbalAdd.call(a: 1, b: 2) }
124
+ x.report('Verbalize') { VerbalizeAdd.call(a: 1, b: 2) }
130
125
  x.report('Actionizer') { ActionizerAdd.call(a: 1, b: 2) }
131
126
  x.report('Interactor') { InteractorAdd.call(a: 1, b: 2) }
132
127
  x.compare!
@@ -134,22 +129,23 @@ end
134
129
  ```
135
130
 
136
131
  ```
132
+ Warming up --------------------------------------
133
+ Ruby 53.203k i/100ms
134
+ Verbalize 27.518k i/100ms
135
+ Actionizer 4.933k i/100ms
136
+ Interactor 4.166k i/100ms
137
137
  Calculating -------------------------------------
138
- Interactor 4619 i/100ms
139
- Actionizer 4919 i/100ms
140
- Verbal 21841 i/100ms
141
- Ruby 43212 i/100ms
142
- -------------------------------------------------
143
- Interactor 46966.6 (±7.5%) i/s - 235569 in 5.046586s
144
- Actionizer 48493.5 (±6.0%) i/s - 245950 in 5.091045s
145
- Verbal 259273.2 (±4.7%) i/s - 1310460 in 5.065844s
146
- Ruby 618459.0 (±5.4%) i/s - 3111264 in 5.046011s
138
+ Ruby 544.025k (±13.7%) i/s - 2.660M in 5.011207s
139
+ Verbalize 278.738k (± 8.0%) i/s - 1.403M in 5.074676s
140
+ Actionizer 49.571k (± 7.0%) i/s - 246.650k in 5.006194s
141
+ Interactor 45.896k (± 7.1%) i/s - 229.130k in 5.018389s
147
142
 
148
143
  Comparison:
149
- Ruby: 618459.0 i/s
150
- Verbal: 259273.2 i/s - 2.39x slower
151
- Actionizer: 48493.5 i/s - 12.75x slower
152
- Interactor: 46966.6 i/s - 13.17x slower
144
+ Ruby: 544025.0 i/s
145
+ Verbalize: 278737.9 i/s - 1.95x slower
146
+ Actionizer: 49571.1 i/s - 10.97x slower
147
+ Interactor: 45896.1 i/s - 11.85x slower
148
+
153
149
  ```
154
150
 
155
151
  ## Installation
data/lib/verbalize.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  require 'verbalize/version'
2
- require 'verbalize/build_initialize'
3
- require 'verbalize/build_action'
4
- require 'verbalize/build_attributes'
5
- require 'verbalize/build_argument_validator'
2
+ require 'verbalize/build_initialize_method'
3
+ require 'verbalize/build_action_method'
4
+ require 'verbalize/build_attribute_readers'
6
5
  require 'verbalize/result'
7
6
 
8
7
  module Verbalize
@@ -20,23 +19,47 @@ module Verbalize
20
19
  end
21
20
 
22
21
  module ClassMethods
23
- def call
24
- action = new
25
- value = catch(:verbalize_error) { action.call }
26
- Result.new(outcome: action.outcome, value: value)
22
+ def verbalize(*arguments, **keyword_arguments)
23
+ method_name, *arguments = arguments
24
+ input(*arguments, method_name: method_name, **keyword_arguments)
27
25
  end
28
26
 
29
- def input(*arguments, verbalize_method_name: :call, **keyword_arguments)
30
- raise ArgumentError unless keyword_arguments.empty?
31
- class_eval BuildAction.new(arguments, verbalize_method_name).build
32
- class_eval BuildInitialize.new(arguments).build
33
- class_eval BuildAttributes.new(arguments).build
34
- class_eval BuildArgumentValidator.new(arguments).build
27
+ def input( # rubocop:disable Metrics/MethodLength
28
+ *required_keywords,
29
+ optional: [],
30
+ method_name: :call,
31
+ **other_keyword_arguments
32
+ )
33
+
34
+ unless other_keyword_arguments.empty?
35
+ raise(
36
+ ArgumentError,
37
+ "Unsupported keyword arguments received: #{other_keyword_arguments.inspect}"
38
+ )
39
+ end
40
+
41
+ optional_keywords = Array(optional)
42
+
43
+ class_eval BuildActionMethod.call(
44
+ required_keywords: required_keywords,
45
+ optional_keywords: optional_keywords,
46
+ method_name: method_name
47
+ )
48
+
49
+ class_eval BuildInitializeMethod.call(
50
+ required_keywords: required_keywords,
51
+ optional_keywords: optional_keywords
52
+ )
53
+
54
+ class_eval BuildAttributeReaders.call(
55
+ attributes: required_keywords + optional_keywords
56
+ )
35
57
  end
36
58
 
37
- def verbalize(*arguments, **keyword_arguments)
38
- method_name, *arguments = arguments
39
- input(*arguments, verbalize_method_name: method_name, **keyword_arguments)
59
+ def call
60
+ action = new
61
+ value = catch(:verbalize_error) { action.call }
62
+ Result.new(outcome: action.outcome, value: value)
40
63
  end
41
64
  end
42
65
  end
@@ -1,7 +1,7 @@
1
1
  require_relative 'build_method_base'
2
2
 
3
3
  module Verbalize
4
- class BuildAction < BuildMethodBase
4
+ class BuildActionMethod < BuildMethodBase
5
5
  private
6
6
 
7
7
  def declaration
@@ -11,14 +11,13 @@ module Verbalize
11
11
  def body
12
12
  [
13
13
  "action = new(#{initialize_keyword_arguments})",
14
- '_verbalize_validate_arguments(action)',
15
14
  "value = catch(:verbalize_error) { action.#{method_name} }",
16
15
  'Result.new(outcome: action.outcome, value: value)'
17
16
  ].join("\n")
18
17
  end
19
18
 
20
19
  def initialize_keyword_arguments
21
- keywords.map { |variable| "#{variable}: #{variable}" }.join(', ')
20
+ all_keywords.map { |variable| "#{variable}: #{variable}" }.join(', ')
22
21
  end
23
22
  end
24
23
  end
@@ -0,0 +1,20 @@
1
+ module Verbalize
2
+ class BuildAttributeReaders
3
+ def self.call(attributes: [])
4
+ new(attributes: attributes).call
5
+ end
6
+
7
+ def initialize(attributes: [])
8
+ @attributes = attributes
9
+ end
10
+
11
+ def call
12
+ return '' if attributes.empty?
13
+ "attr_reader #{attributes.map(&:inspect).join ', '}"
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :attributes
19
+ end
20
+ end
@@ -1,7 +1,7 @@
1
1
  require_relative 'build_method_base'
2
2
 
3
3
  module Verbalize
4
- class BuildInitialize < BuildMethodBase
4
+ class BuildInitializeMethod < BuildMethodBase
5
5
  private
6
6
 
7
7
  def declaration
@@ -9,9 +9,9 @@ module Verbalize
9
9
  end
10
10
 
11
11
  def body
12
- return if keywords.empty?
12
+ return if all_keywords.empty?
13
13
 
14
- lines = keywords.map do |keyword|
14
+ lines = all_keywords.map do |keyword|
15
15
  "@#{keyword} = #{keyword}"
16
16
  end
17
17
 
@@ -1,16 +1,25 @@
1
1
  class BuildMethodBase
2
- def initialize(keywords, method_name = :call)
3
- @keywords = keywords
4
- @method_name = method_name
2
+ def self.call(required_keywords: [], optional_keywords: [], method_name: :call)
3
+ new(
4
+ required_keywords: required_keywords,
5
+ optional_keywords: optional_keywords,
6
+ method_name: method_name
7
+ ).call
5
8
  end
6
9
 
7
- def build
10
+ def initialize(required_keywords: [], optional_keywords: [], method_name: :call)
11
+ @required_keywords = required_keywords
12
+ @optional_keywords = optional_keywords
13
+ @method_name = method_name
14
+ end
15
+
16
+ def call
8
17
  parts.compact.join "\n"
9
18
  end
10
19
 
11
20
  private
12
21
 
13
- attr_reader :keywords, :method_name
22
+ attr_reader :required_keywords, :optional_keywords, :method_name
14
23
 
15
24
  def parts
16
25
  [declaration, body, 'end']
@@ -24,8 +33,20 @@ class BuildMethodBase
24
33
  raise NotImplementedError
25
34
  end
26
35
 
36
+ def all_keywords
37
+ required_keywords + optional_keywords
38
+ end
39
+
40
+ def required_keyword_segments
41
+ required_keywords.map { |keyword| "#{keyword}:" }
42
+ end
43
+
44
+ def optional_keyword_segments
45
+ optional_keywords.map { |keyword| "#{keyword}: nil" }
46
+ end
47
+
27
48
  def declaration_keyword_arguments
28
- return if keywords.empty?
29
- keywords.map { |keyword| "#{keyword}: nil" }.join(', ')
49
+ return if all_keywords.empty?
50
+ (required_keyword_segments + optional_keyword_segments).join(', ')
30
51
  end
31
52
  end
@@ -1,3 +1,3 @@
1
1
  module Verbalize
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verbalize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Taylor
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-08-07 00:00:00.000000000 Z
11
+ date: 2016-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -113,10 +113,9 @@ files:
113
113
  - bin/setup
114
114
  - circle.yml
115
115
  - lib/verbalize.rb
116
- - lib/verbalize/build_action.rb
117
- - lib/verbalize/build_argument_validator.rb
118
- - lib/verbalize/build_attributes.rb
119
- - lib/verbalize/build_initialize.rb
116
+ - lib/verbalize/build_action_method.rb
117
+ - lib/verbalize/build_attribute_readers.rb
118
+ - lib/verbalize/build_initialize_method.rb
120
119
  - lib/verbalize/build_method_base.rb
121
120
  - lib/verbalize/result.rb
122
121
  - lib/verbalize/version.rb
@@ -1,36 +0,0 @@
1
- require_relative 'build_method_base'
2
-
3
- module Verbalize
4
- class BuildArgumentValidator < BuildMethodBase
5
- private
6
-
7
- def declaration
8
- 'def self._verbalize_validate_arguments(instance)'
9
- end
10
-
11
- def body
12
- return if keywords.empty?
13
- (check_values + raise_error_if_necessary).join("\n")
14
- end
15
-
16
- def check_values
17
- [
18
- "keywords = [#{keywords.map(&:inspect).join(', ')}]",
19
- 'keywords_without_values = keywords.select do |keyword|',
20
- ' instance.send(keyword).nil?',
21
- 'end'
22
- ]
23
- end
24
-
25
- def raise_error_if_necessary
26
- [
27
- 'if keywords_without_values.any?',
28
- " error_message = 'missing keyword'",
29
- " error_message += 's' if keywords_without_values.count > 1",
30
- %q{ error_message += ": #{keywords_without_values.join(', ')}"},
31
- ' raise ArgumentError.new(error_message)',
32
- 'end'
33
- ]
34
- end
35
- end
36
- end
@@ -1,16 +0,0 @@
1
- module Verbalize
2
- class BuildAttributes
3
- def initialize(keywords)
4
- @keywords = keywords
5
- end
6
-
7
- def build
8
- return '' if keywords.empty?
9
- "attr_reader #{keywords.map(&:inspect).join ', '}"
10
- end
11
-
12
- private
13
-
14
- attr_reader :keywords
15
- end
16
- end