dry-behaviour 0.8.0 → 0.9.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: c9950cb0ec4cecfed71f7cae1cd777a0693ed8b5
4
- data.tar.gz: a77cc845e72319b08e222e3ab7c820f87359e6a2
3
+ metadata.gz: b2b0ca314a414ad6f7d6a03ab29a2fc0b1979e48
4
+ data.tar.gz: 2367933ab2b964b9bbfaadf22be72017d2f79a03
5
5
  SHA512:
6
- metadata.gz: d7f410dc7fb586256831916469d2d7bdcd74361235a74c891ac90ea8609bc69e343d9585d211a8b91abd9f88b443a60509bb9418df4201917fc01e170815346a
7
- data.tar.gz: f4d1c1116169906a8efc11ea289c45d150cd920a3dcc2cbbc2c0f73870f449b2f102478e3a5aa54d6fb5a8c9e1d87031532f57a147d322d9d41d6ba885be75cc
6
+ metadata.gz: da6989a23ce8f768967a5627e5f276114edfa94a9eb1d5b29286ec0617bf9bde29b5011748230d7717e1912c731365a94798a70d57943e57d3be867baf8c10da
7
+ data.tar.gz: 1580b12c2f74a616218f3789a9425f3f737483eccae31be53366a0ab9835f66d51c373839ce5c9ec725b9767b0397d15c7d66123661127e214345ba7415ef3e7
data/README.md CHANGED
@@ -100,6 +100,11 @@ end
100
100
 
101
101
  ## Changelog
102
102
 
103
+ ### `0.9.0` :: Warning On Wrong Arity
104
+
105
+ - many error reporting improvements,
106
+ - warning on wrong arity (declaration, arity 0 / implementation, wrong arity)
107
+
103
108
  ### `0.8.0` :: Implicit Inheritance
104
109
 
105
110
  - deprecate implicit delegation to the target instance; error message saying “it’ll be removed in 1.0”
@@ -62,35 +62,21 @@ module Dry
62
62
  end
63
63
 
64
64
  def defmethod(name, *params)
65
- BlackTie.protocols[self][name] = params
66
- end
67
-
68
- DELEGATE_METHOD = lambda do |klazz, (source, target)|
69
- klazz.class_eval do
70
- define_method(source, &Dry::DEFINE_METHOD.curry[target])
65
+ if params.size.zero? || params.first.is_a?(Array) && params.first.last != :req
66
+ BlackTie.Logger.warn(IMPLICIT_RECEIVER_DECLARATION % [Dry::BlackTie.proto_caller, self.inspect, name])
67
+ params.unshift(:this)
71
68
  end
72
- end
73
-
74
- POSTPONE_EXTEND = lambda do |target, protocol|
75
- TracePoint.new(:end) do |tp|
76
- if tp.self == protocol
77
- target.extend protocol
78
- tp.disable
69
+ params =
70
+ params.map do |p, type|
71
+ if type && !PARAM_TYPES.include?(type)
72
+ BlackTie.Logger.warn(UNKNOWN_TYPE_DECLARATION % [Dry::BlackTie.proto_caller, type, self.inspect, name])
73
+ type = nil
74
+ end
75
+ [type || PARAM_TYPES.include?(p) ? p : :req, p]
79
76
  end
80
- end.enable
81
- end
82
-
83
- NORMALIZE_KEYS = lambda do |protocol|
84
- BlackTie.protocols[protocol].keys.reject { |k| k.to_s =~ /\A__.*__\z/ }
77
+ BlackTie.protocols[self][name] = params
85
78
  end
86
79
 
87
- IMPLICIT_DELEGATE_DEPRECATION =
88
- "\n⚠️ DEPRECATED → Implicit delegation to the target class will be removed in 1.0\n" \
89
- "  ⮩ due to the lack of the explicit implementation of %s#%s for %s\n" \
90
- "  ⮩ it will be delegated to the target class itself.\n" \
91
- "  ⮩ Consider using explicit `delegate:' declaration in `defimpl' or\n" \
92
- "  ⮩ use `implicit_inheritance: true' parameter in protocol definition.".freeze
93
-
94
80
  def defimpl(protocol = nil, target: nil, delegate: [], map: {}, &λ)
95
81
  raise if target.nil? || !block_given? && delegate.empty? && map.empty?
96
82
 
@@ -106,13 +92,13 @@ module Dry
106
92
  (NORMALIZE_KEYS.(protocol) - meths).each_with_object(meths) do |m, acc|
107
93
  if BlackTie.protocols[protocol][:__implicit_inheritance__]
108
94
  mod.singleton_class.class_eval do
109
- define_method m do |*args, &λ|
110
- super(*args, )
95
+ define_method m do |this, *♿_args, &♿_λ|
96
+ super(this, *♿_args, &♿_λ)
111
97
  end
112
98
  end
113
99
  else
114
100
  BlackTie.Logger.warn(
115
- IMPLICIT_DELEGATE_DEPRECATION % [protocol.inspect, m, target]
101
+ IMPLICIT_DELEGATE_DEPRECATION % [Dry::BlackTie.proto_caller, protocol.inspect, m, target]
116
102
  )
117
103
  DELEGATE_METHOD.(mod.singleton_class, [m] * 2)
118
104
  end
@@ -121,6 +107,17 @@ module Dry
121
107
  end.each do |m|
122
108
  target = [target] unless target.is_a?(Array)
123
109
  target.each do |tgt|
110
+ ok =
111
+ [
112
+ BlackTie.protocols[protocol][m],
113
+ mod.method(m).parameters.reject { |_, v| v.to_s[/\A♿_/] }
114
+ ].map(&:first).reduce(:==)
115
+
116
+ # TODO[1.0] raise NotImplemented(:arity)
117
+ BlackTie.Logger.warn(
118
+ WRONG_PARAMETER_DECLARATION % [Dry::BlackTie.proto_caller, protocol.inspect, m, target, BlackTie.protocols[protocol][m].map(&:first)]
119
+ ) unless ok
120
+
124
121
  BlackTie.implementations[protocol][tgt][m] = mod.method(m).to_proc
125
122
  end
126
123
  end
@@ -128,6 +125,60 @@ module Dry
128
125
  end
129
126
  module_function :defimpl
130
127
 
128
+ PARAM_TYPES = %i[req opt rest keyrest block]
129
+
130
+ DELEGATE_METHOD = lambda do |klazz, (source, target)|
131
+ klazz.class_eval do
132
+ define_method(source, &Dry::DEFINE_METHOD.curry[target])
133
+ end
134
+ end
135
+
136
+ POSTPONE_EXTEND = lambda do |target, protocol|
137
+ TracePoint.new(:end) do |tp|
138
+ if tp.self == protocol
139
+ target.extend protocol
140
+ tp.disable
141
+ end
142
+ end.enable
143
+ end
144
+
145
+ NORMALIZE_KEYS = lambda do |protocol|
146
+ BlackTie.protocols[protocol].keys.reject { |k| k.to_s =~ /\A__.*__\z/ }
147
+ end
148
+
149
+ def self.proto_caller
150
+ caller.drop_while do |line|
151
+ line =~ %r[dry-behaviour/lib/dry/behaviour]
152
+ end.first
153
+ end
154
+
155
+ IMPLICIT_DELEGATE_DEPRECATION =
156
+ "\n🚨️ DEPRECATED → %s\n" \
157
+ "  ⮩ Implicit delegation to the target class will be removed in 1.0\n" \
158
+ "  ⮩ due to the lack of the explicit implementation of %s#%s for %s\n" \
159
+ "  ⮩ it will be delegated to the target class itself.\n" \
160
+ "  ⮩ Consider using explicit `delegate:' declaration in `defimpl' or\n" \
161
+ "  ⮩ use `implicit_inheritance: true' parameter in protocol definition.".freeze
162
+
163
+ IMPLICIT_RECEIVER_DECLARATION =
164
+ "\n⚠️ TOO IMPLICIT → %s\n" \
165
+ "  ⮩ Implicit declaration of `this' parameter in `defmethod'.\n" \
166
+ "  ⮩ Whilst it’s allowed, we strongly encourage to explicitly declare it\n" \
167
+ "  ⮩ in call to %s#defmethod(%s).".freeze
168
+
169
+ UNKNOWN_TYPE_DECLARATION =
170
+ "\n⚠️ UNKNOWN TYPE → %s\n" \
171
+ "  ⮩ Unknown parameter type [%s] in call to %s#defmethod(%s).\n" \
172
+ "  ⮩ Is it a typo? Omit the type for `:req' or pass one of allowed types:\n" \
173
+ "  ⮩ #{PARAM_TYPES.inspect}".freeze
174
+
175
+ WRONG_PARAMETER_DECLARATION =
176
+ "\n🚨️ DEPRECATED → %s\n" \
177
+ "  ⮩ Wrong parameters declaration will be removed in 1.0\n" \
178
+ "  ⮩ %s#%s was implemented for %s with unexpected parameters.\n" \
179
+ "  ⮩ Consider implementing interfaces exactly as they were declared.\n" \
180
+ "  ⮩ Expected: %s".freeze
181
+
131
182
  def self.Logger
132
183
  @logger ||= if Kernel.const_defined?('::Rails')
133
184
  Rails.logger
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Behaviour
3
- VERSION = '0.8.0'.freeze
3
+ VERSION = '0.9.0'.freeze
4
4
  end
5
5
  end
@@ -18,6 +18,14 @@ module Dry
18
18
  " ⮩ Caused by “#{cause.class}” with a message\n" \
19
19
  " ⮩ “#{cause.message}”\n" \
20
20
  " ⮩ Rescue this exception and inspect `NotImplemented#cause' for details."
21
+ when :arity
22
+ "Attempt to implement “#{@proto}#@details[:method]}”\n" \
23
+ " ⮩ with a wrong arity for “#{@details[:target]}”.\n" \
24
+ " ⮩ Expected parameters types:\n" \
25
+ " ⮩ “#{@details[:expected]}”\n" \
26
+ " ⮩ Provided parameters types:\n" \
27
+ " ⮩ “#{@details[:provided]}”\n" \
28
+ " ⮩ Please consider providing a proper implementation."
21
29
  else
22
30
  "Protocol “#{proto}” is invalid."
23
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-behaviour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aleksei Matiushkin
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-10-11 00:00:00.000000000 Z
13
+ date: 2018-10-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler