dry-behaviour 0.11.2 → 0.12.1

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
- 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