dry-behaviour 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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