dry-behaviour 0.11.2 → 0.12.1

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
- SHA256:
3
- metadata.gz: 232921c25386484f9538bbe49039c133c1de8e2d2cd85b9545a4de3736344385
4
- data.tar.gz: 38625102473e08efc17d5162db60e1fc9a90633f81695ecb60f26f395237f976
2
+ SHA1:
3
+ metadata.gz: e6de5e26b1d3d57039660055f9248c1a3df5431d
4
+ data.tar.gz: 17404270b966673dd7d7c56d6966d1a93cf58cfd
5
5
  SHA512:
6
- metadata.gz: 4c4c5d71d32fcfe4bef6fb13e21ddcd8a32afc63cdbf3bda1dc97428d56332f99e02fd15cb15db9b3ecafb719812e6889587794598dd666335d02e67780b6ae9
7
- data.tar.gz: 3d556f70828ded92ad615fd01ab27b1d7b4c70843bf2d16fa10de1a9102da08ea6f3284883aa2c37a2b0c830776c36ea5ed989cb50ef711e29c5dbb2cfa53531
6
+ metadata.gz: bb1ddcc3af289266d79dfd8c38b33fd47f4db8f3d2533e4aec395ff353490876bbf2554e241b23c5e56b45b81bec623f79baa97eede969071ab07c7ab7e24eba
7
+ data.tar.gz: 02e81fe058128b1ebdbb4fe34ed5811c9bd6da01ab91742235bb57f87b29adfc3824d33885e507137e724fffac7d793d3a33da7882b4dc766de8601a7df43c0e
@@ -3,18 +3,22 @@ name: Ruby
3
3
  on: [push]
4
4
 
5
5
  jobs:
6
- build:
6
+ test:
7
7
 
8
8
  runs-on: ubuntu-latest
9
9
 
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ ruby-version: ['head', '3.1', '3.0', '2.7']
14
+
10
15
  steps:
11
- - uses: actions/checkout@v1
12
- - name: Set up Ruby 2.6
13
- uses: actions/setup-ruby@v1
14
- with:
15
- ruby-version: 2.6.x
16
- - name: Build and test with Rake
17
- run: |
18
- gem install bundler
19
- bundle install --jobs 4 --retry 3
20
- bundle exec rake
16
+ - uses: actions/checkout@v3
17
+ - name: Set up Ruby ${{ matrix.ruby-version }}
18
+ uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
19
+ with:
20
+ ruby-version: ${{ matrix.ruby-version }}
21
+ - name: Install dependencies
22
+ run: bundle install --jobs 4 --retry 3
23
+ - name: Run tests
24
+ run: bundle exec rspec
@@ -15,10 +15,10 @@ jobs:
15
15
 
16
16
  steps:
17
17
  - uses: actions/checkout@master
18
- - name: Set up Ruby 2.6
19
- uses: actions/setup-ruby@v1
18
+ - name: Set up Ruby 2.3.8
19
+ uses: ruby/setup-ruby@v1
20
20
  with:
21
- version: 2.6.x
21
+ version: 2.3.8
22
22
 
23
23
  - name: Publish to GPR
24
24
  run: |
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 2.3.8
data/README.md CHANGED
@@ -60,6 +60,45 @@ expect(Protocols::Adder.add(nil, 10)).to eq(10)
60
60
  expect(Protocols::Adder.add_default(1)).to eq(6)
61
61
  ```
62
62
 
63
+ ### Arguments types
64
+
65
+ Normally, one would use a simple notation to declare a method. It includes `:this` receiver
66
+ in te very first position and some optional required arguments afterward.
67
+
68
+ ```ruby
69
+ defmethod :add, :this, :addend
70
+ ...
71
+ defimpl ... do
72
+ def add(this, addend); this + addend; end
73
+ end
74
+ ```
75
+
76
+ If the argument is not generic (optional, or splatted, or keyword,) its type must be explicitly
77
+ specified in the protocol definition as shown below.
78
+
79
+ ```ruby
80
+ defprotocol implicit_inheritance: true do
81
+ defmethod :with_def_argument, :this, [:foo_opt, :opt]
82
+ defmethod :with_def_keyword_argument, :this, [:foo_key, :key]
83
+ defmethod :with_req_keyword_argument, :this, [:foo_key, :keyreq]
84
+
85
+ def with_def_argument(this, foo_opt = :super); foo_opt; end
86
+ def with_def_keyword_argument(this, foo_key: :super); foo_key; end
87
+ def with_req_keyword_argument(this, foo_key:); foo_key; end
88
+ ...
89
+ ```
90
+
91
+ That said, `:addend` argument declaration is a syntactic sugar for `[:addend, :req]`.
92
+ Possible values for the type are:
93
+
94
+ ```ruby
95
+ PARAM_TYPES = %i[req opt rest key keyrest keyreq block]
96
+ ```
97
+
98
+ Please note, that the signature of the method and its implementation must exactly match.
99
+ One cannot declare a method to have a `keyreq` argument and then make it defaulted in the
100
+ implementation. That is done by design.
101
+
63
102
  ## Guards
64
103
 
65
104
  Starting with `v0.5.0` we support multiple function clauses and guards.
@@ -8,7 +8,7 @@ module Dry
8
8
  class << self
9
9
  def proto_caller
10
10
  caller.drop_while do |line|
11
- line =~ %r[dry-behaviour/lib/dry/behaviour]
11
+ line =~ %r{dry-behaviour/lib/dry/behaviour}
12
12
  end.first
13
13
  end
14
14
 
@@ -20,7 +20,7 @@ module Dry
20
20
  require 'logger'
21
21
  Logger.new($stdout)
22
22
  end
23
- @logger ? @logger : Class.new { def warn(*); end }.new
23
+ @logger || Class.new { def warn(*); end }.new
24
24
  end
25
25
 
26
26
  def protocols
@@ -33,8 +33,8 @@ module Dry
33
33
  end
34
34
 
35
35
  def defprotocol(implicit_inheritance: false, &λ)
36
- raise ::Dry::Protocol::DuplicateDefinition.new(self) if BlackTie.protocols.key?(self)
37
- raise ::Dry::Protocol::MalformedDefinition.new(self) unless block_given?
36
+ raise ::Dry::Protocol::DuplicateDefinition, self if BlackTie.protocols.key?(self)
37
+ raise ::Dry::Protocol::MalformedDefinition, self unless block_given?
38
38
 
39
39
  BlackTie.protocols[self][:__implicit_inheritance__] = !!implicit_inheritance
40
40
 
@@ -54,21 +54,38 @@ module Dry
54
54
  end.reject(&:nil?).first
55
55
  end
56
56
 
57
- BlackTie.protocols[self].each do |method, *_| # FIXME: CHECK ARITY HERE
58
- singleton_class.send :define_method, method do |receiver = nil, *args|
57
+ BlackTie.protocols[self].each do |method, *_m_args, **_m_kwargs| # FIXME: CHECK ARITY HERE
58
+ # singleton_class.send :define_method, method do |receiver, *args, **kwargs|
59
+ singleton_class.send :define_method, method do |*args, **kwargs|
60
+ if args == []
61
+ receiver = kwargs
62
+ kwargs = {}
63
+ else
64
+ receiver, *args = args
65
+ end
66
+
59
67
  impl = implementation_for(receiver)
60
- raise Dry::Protocol::NotImplemented.new(
61
- :protocol, inspect,
62
- method: method, receiver: receiver, args: args, self: self
63
- ) unless impl
68
+
69
+ unless impl
70
+ raise Dry::Protocol::NotImplemented.new(
71
+ :protocol, inspect,
72
+ method: method, receiver: receiver, args: args, self: self
73
+ )
74
+ end
75
+
64
76
  begin
65
- impl[method].(*args.unshift(receiver))
66
- rescue => e
77
+ # [AM] [v1] [FIXME] for modern rubies `if` is redundant
78
+ if kwargs.empty?
79
+ impl[method].(*args.unshift(receiver))
80
+ else
81
+ impl[method].(*args.unshift(receiver), **kwargs)
82
+ end
83
+ rescue StandardError => e
67
84
  raise Dry::Protocol::NotImplemented.new(
68
- :nested, inspect,
69
- cause: e,
70
- method: method, receiver: receiver, args: args, impl: impl, self: self
71
- )
85
+ :nested, inspect,
86
+ cause: e,
87
+ method: method, receiver: receiver, args: args, impl: impl, self: self
88
+ )
72
89
  end
73
90
  end
74
91
  end
@@ -80,16 +97,16 @@ module Dry
80
97
 
81
98
  def defmethod(name, *params)
82
99
  if params.size.zero? || params.first.is_a?(Array) && params.first.last != :req
83
- BlackTie.Logger.warn(IMPLICIT_RECEIVER_DECLARATION % [Dry::BlackTie.proto_caller, self.inspect, name])
100
+ BlackTie.Logger.warn(format(IMPLICIT_RECEIVER_DECLARATION, Dry::BlackTie.proto_caller, inspect, name))
84
101
  params.unshift(:this)
85
102
  end
86
103
  params =
87
104
  params.map do |p, type|
88
105
  if type && !PARAM_TYPES.include?(type)
89
- BlackTie.Logger.warn(UNKNOWN_TYPE_DECLARATION % [Dry::BlackTie.proto_caller, type, self.inspect, name])
106
+ BlackTie.Logger.warn(format(UNKNOWN_TYPE_DECLARATION, Dry::BlackTie.proto_caller, type, inspect, name))
90
107
  type = nil
91
108
  end
92
- [type || PARAM_TYPES.include?(p) ? p : :req, p]
109
+ [type || (PARAM_TYPES.include?(p) ? p : :req), p]
93
110
  end
94
111
  BlackTie.protocols[self][name] = params
95
112
  end
@@ -109,13 +126,18 @@ module Dry
109
126
  (NORMALIZE_KEYS.(protocol) - meths).each_with_object(meths) do |m, acc|
110
127
  if BlackTie.protocols[protocol][:__implicit_inheritance__]
111
128
  mod.singleton_class.class_eval do
112
- define_method m do |this, *♿_args, &♿_λ|
113
- super(this, *♿_args, &♿_λ)
129
+ define_method m do |this, *♿_args, **♿_kwargs, &♿_λ|
130
+ # [AM] [v1] [FIXME] for modern rubies `if` is redundant
131
+ if ♿_kwargs.empty?
132
+ super(this, *♿_args, &♿_λ)
133
+ else
134
+ super(this, *♿_args, **♿_kwargs, &♿_λ)
135
+ end
114
136
  end
115
137
  end
116
138
  else
117
139
  BlackTie.Logger.warn(
118
- IMPLICIT_DELEGATE_DEPRECATION % [Dry::BlackTie.proto_caller, protocol.inspect, m, target]
140
+ format(IMPLICIT_DELEGATE_DEPRECATION, Dry::BlackTie.proto_caller, protocol.inspect, m, target)
119
141
  )
120
142
  DELEGATE_METHOD.(mod.singleton_class, [m] * 2)
121
143
  end
@@ -128,13 +150,17 @@ module Dry
128
150
  proto = BlackTie.protocols[protocol]
129
151
  ok =
130
152
  mds.map(&:first).include?(m) ||
131
- ((proto[m] == {} || proto[:__implicit_inheritance__]) && [[:req], [:rest]].include?(params.map(&:first))) ||
153
+ ((proto[m] == {} || proto[:__implicit_inheritance__]) && [[:req],
154
+ [:rest]].include?(params.map(&:first))) ||
132
155
  [proto[m], params].map { |args| args.map(&:first) }.reduce(:==)
133
156
 
134
157
  # TODO[1.0] raise NotImplemented(:arity)
135
- BlackTie.Logger.warn(
136
- WRONG_PARAMETER_DECLARATION % [Dry::BlackTie.proto_caller, protocol.inspect, m, target, BlackTie.protocols[protocol][m].map(&:first)]
137
- ) unless ok
158
+ unless ok
159
+ BlackTie.Logger.warn(
160
+ format(WRONG_PARAMETER_DECLARATION, Dry::BlackTie.proto_caller, protocol.inspect, m, target,
161
+ BlackTie.protocols[protocol][m].map(&:first))
162
+ )
163
+ end
138
164
 
139
165
  BlackTie.implementations[protocol][tgt][m] = mod.method(m).to_proc
140
166
  end
@@ -143,7 +169,7 @@ module Dry
143
169
  end
144
170
  module_function :defimpl
145
171
 
146
- PARAM_TYPES = %i[req opt rest keyrest block]
172
+ PARAM_TYPES = %i[req opt rest key keyrest keyreq block]
147
173
 
148
174
  DELEGATE_METHOD = lambda do |klazz, (source, target)|
149
175
  klazz.class_eval do
@@ -176,7 +202,7 @@ module Dry
176
202
  "\n⚠️ TOO IMPLICIT → %s\n" \
177
203
  "  ⮩ Implicit declaration of `this' parameter in `defmethod'.\n" \
178
204
  "  ⮩ Whilst it’s allowed, we strongly encourage to explicitly declare it\n" \
179
- "  ⮩ in call to %s#defmethod(%s).".freeze
205
+ '  ⮩ in call to %s#defmethod(%s).'.freeze
180
206
 
181
207
  UNKNOWN_TYPE_DECLARATION =
182
208
  "\n⚠️ UNKNOWN TYPE → %s\n" \
@@ -189,7 +215,7 @@ module Dry
189
215
  "  ⮩ Wrong parameters declaration will be removed in 1.0\n" \
190
216
  "  ⮩ %s#%s was implemented for %s with unexpected parameters.\n" \
191
217
  "  ⮩ Consider implementing interfaces exactly as they were declared.\n" \
192
- "  ⮩ Expected: %s".freeze
218
+ '  ⮩ Expected: %s'.freeze
193
219
 
194
220
  private
195
221
 
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Behaviour
3
- VERSION = '0.11.2'.freeze
3
+ VERSION = '0.12.1'.freeze
4
4
  end
5
5
  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.11.2
4
+ version: 0.12.1
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: 2022-07-08 00:00:00.000000000 Z
13
+ date: 2023-02-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -111,7 +111,7 @@ files:
111
111
  - ".rspec"
112
112
  - ".rubocop.yml"
113
113
  - ".rubocop_todo.yml"
114
- - ".travis.yml"
114
+ - ".tool-versions"
115
115
  - CODE_OF_CONDUCT.md
116
116
  - Gemfile
117
117
  - LICENSE.txt
@@ -149,7 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  - !ruby/object:Gem::Version
150
150
  version: '0'
151
151
  requirements: []
152
- rubygems_version: 3.3.3
152
+ rubyforge_project:
153
+ rubygems_version: 2.5.2.3
153
154
  signing_key:
154
155
  specification_version: 4
155
156
  summary: Tiny library inspired by Elixir protocol pattern.
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.1
4
- - 2.1.10
5
- - 2.2.2
6
- - 2.5.1
7
- before_install: gem install bundler -v 1.14.6