signal 0.3.0 → 1.3.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
- SHA1:
3
- metadata.gz: f93acc02fac0dc15d821540be7b8429a1c4ee767
4
- data.tar.gz: ccbf61c85f7448b07f32e5a708905862b63a66f3
2
+ SHA256:
3
+ metadata.gz: b9b02225af7234c06c7bdca60c54ca2bc5bd7b56760350fb52c603dcfcd9c6fc
4
+ data.tar.gz: 6ae6ad7189173f3eef745a12b0bba61444a00b6ed6da7680848d8fdfa26c9214
5
5
  SHA512:
6
- metadata.gz: edebdf9690ad027d27f25a1e80d94272750b1a62434df184d6894c7a253b0f050fe06dda337601179886d22b02d4bffeb5155e695a8d7d09b27f88aef4f3d1f6
7
- data.tar.gz: 055b3b383611a0de961f0f66d4cfd7b0b40fcfc36dd252e46d2cdade60dd34b9f73ce50bd07a4e677e596063c3154dbb96687ac788236d4cad9e06a6a15526ac
6
+ metadata.gz: aba54da3377c2f2eb8eca0d87edc44599dccb195259bf75949008cd17b780f7d2ad9fbce0e54aac6b3e2fd63e0bf61e86f02ad1e02e4bd4b5ba9c6a96baa74c9
7
+ data.tar.gz: b7be39534802b24399c9d732c7af050447b66ac5fff04abd6ee66f46f54324e6e6f636c2d84b62c0f20c490fc471484d3ee86e6f5faca3b833d5a8d17761fcdf
@@ -0,0 +1,3 @@
1
+ ---
2
+ github: [fnando]
3
+ custom: ["https://www.paypal.me/nandovieira/🍕"]
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ ---
2
+ inherit_gem:
3
+ rubocop-fnando: .rubocop.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.7
7
+ Exclude:
8
+ - vendor/**/*
9
+ - gemfiles/**/*
10
+
11
+ Metrics:
12
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,12 +1,20 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  sudo: false
4
- script: bundle exec rspec
4
+ script: bundle exec rake
5
5
  rvm:
6
- - '2.2'
7
- - '2.1'
8
- - '2.0'
9
- addons:
10
- code_climate:
11
- repo_token:
12
- secure: "ASogQTLS/xYYczRtFwuo8DIkNdOl16mez4GHOw4RtdfTQ4BMROxE/CUemdPulMW1b/p7jsp5ghOtH2EJ4jN203s83HN4QjGC2wXhigkk6LzvxqjkmHxIWxJi2JS2sLq8nzOCcD0geO1pcbBFyuAzAdlwWa2g1WDP7O0L0fNjCtM="
6
+ - 2.7.1
7
+ - 2.6.2
8
+ before_script:
9
+ - "curl -L
10
+ https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
11
+ > ./cc-test-reporter"
12
+ - chmod +x ./cc-test-reporter
13
+ - "./cc-test-reporter before-build"
14
+ after_script:
15
+ - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
16
+ notifications:
17
+ email: false
18
+ env:
19
+ global:
20
+ secure: EmzkOnefLJlsAbh4tKzcdfX9PiwQMNSmWz1aTaieA1C9GJryT2JswBa/eVgU3jDKPhFFdZ5X8K6bf0ArAdDXFMW5+DPQ9nWDOCUH3QuuFTOicyTi16W8HCozbLTg49CdB0kP4iQlA3rdpje/T9zgsTvdNDuBevB90JplHy5Lu6o=
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
- source 'http://rubygems.org'
1
+ # frozen_string_literal: true
2
+
3
+ source "http://rubygems.org"
2
4
  gemspec
data/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Signal
2
2
 
3
- [![Build Status](https://travis-ci.org/fnando/signal.svg?branch=master)](https://travis-ci.org/fnando/signal)
3
+ [![Build Status](https://travis-ci.org/fnando/signal.svg?branch=main)](https://travis-ci.org/fnando/signal)
4
4
  [![Code Climate](https://codeclimate.com/github/fnando/signal/badges/gpa.svg)](https://codeclimate.com/github/fnando/signal)
5
5
  [![Test Coverage](https://codeclimate.com/github/fnando/signal/badges/coverage.svg)](https://codeclimate.com/github/fnando/signal)
6
+ [![Gem](https://img.shields.io/gem/v/signal.svg)](https://rubygems.org/gems/signal)
7
+ [![Gem](https://img.shields.io/gem/dt/signal.svg)](https://rubygems.org/gems/signal)
6
8
 
7
- A simple observer implementation on POROs (Plain Old Ruby Object) and ActiveRecord objects.
9
+ A simple observer implementation on POROs (Plain Old Ruby Object) and
10
+ ActiveRecord objects.
8
11
 
9
12
  ## Installation
10
13
 
@@ -28,7 +31,8 @@ You can use Signal with PORO (Plain Old Ruby Object) and ActiveRecord.
28
31
 
29
32
  ### Plain Ruby
30
33
 
31
- All you have to do is including the `Signal` module. Then you can add listeners and trigger events.
34
+ All you have to do is including the `Signal` module. Then you can add listeners
35
+ and trigger events.
32
36
 
33
37
  ```ruby
34
38
  class Status
@@ -49,7 +53,8 @@ status.ready!
49
53
  #=> After the ready event!
50
54
  ```
51
55
 
52
- You can also pass objects that implement methods like `before_*`, `on_*` and `after_*`.
56
+ You can also pass objects that implement methods like `before_*`, `on_*` and
57
+ `after_*`.
53
58
 
54
59
  ```ruby
55
60
  class MyListener
@@ -74,7 +79,9 @@ Status.new
74
79
  #=> After the ready event!
75
80
  ```
76
81
 
77
- Executed blocks don't switch context. You always have to emit the object you're interested in. The follow example uses `emit(:output, self)` to send the `Contact` instance to all listeners.
82
+ Executed blocks don't switch context. You always have to emit the object you're
83
+ interested in. The follow example uses `emit(:output, self)` to send the
84
+ `Contact` instance to all listeners.
78
85
 
79
86
  ```ruby
80
87
  class Contact
@@ -119,11 +126,12 @@ Arguments.new
119
126
 
120
127
  ### ActiveRecord
121
128
 
122
- You can use Signal with ActiveRecord, which will give you some default events like `:create`, `:update`, `:remove` and `:validation`.
129
+ You can use Signal with ActiveRecord, which will give you some default events
130
+ like `:create`, `:update`, `:remove` and `:validation`.
123
131
 
124
132
  ```ruby
125
133
  class Thing < ActiveRecord::Base
126
- include Signal::ActiveRecord
134
+ include Signal.active_record
127
135
 
128
136
  validates_presence_of :name
129
137
  end
@@ -151,22 +159,23 @@ thing.destroy
151
159
 
152
160
  These are the available events:
153
161
 
154
- * `before(:create)`: triggered before creating the record (record is valid).
155
- * `on(:create)`: triggered after `before(:create)` event.
156
- * `after(:create)`: triggered after the `on(:create)` event.
157
- * `before(:update)`: triggered before updating the record (record is valid).
158
- * `on(:update)`: triggered when the `before(:update)` event.
159
- * `after(:update)`: triggered after the `on(:update)` event.
160
- * `before(:remove)`: triggered before removing the record.
161
- * `on(:remove)`: triggered after the `before(:remove)`.
162
- * `after(:remove)`: triggered after the `on(:remove)` event.
163
- * `before(:validation)`: triggered before validating record.
164
- * `on(:validation)`: triggered when record is invalid.
165
- * `after(:validation)`: triggered after validating record.
162
+ - `before(:create)`: triggered before creating the record (record is valid).
163
+ - `on(:create)`: triggered after `before(:create)` event.
164
+ - `after(:create)`: triggered after the `on(:create)` event.
165
+ - `before(:update)`: triggered before updating the record (record is valid).
166
+ - `on(:update)`: triggered when the `before(:update)` event.
167
+ - `after(:update)`: triggered after the `on(:update)` event.
168
+ - `before(:remove)`: triggered before removing the record.
169
+ - `on(:remove)`: triggered after the `before(:remove)`.
170
+ - `after(:remove)`: triggered after the `on(:remove)` event.
171
+ - `before(:validation)`: triggered before validating record.
172
+ - `on(:validation)`: triggered when record is invalid.
173
+ - `after(:validation)`: triggered after validating record.
166
174
 
167
175
  ### Inside Rails
168
176
 
169
- Although there's no special code for Rails, here's just an example of how you can use it:
177
+ Although there's no special code for Rails, here's just an example of how you
178
+ can use it:
170
179
 
171
180
  ```ruby
172
181
  class UsersController < ApplicationController
@@ -197,7 +206,10 @@ end
197
206
 
198
207
  ### Signal::Call
199
208
 
200
- You can include `Signal::Call` instead, so you can have a common interface for your observable object. This will add the `.call()` method to the target class, which will delegate attributes to the observable's `initialize` method and call its `call` method.
209
+ You can include `Signal.call` instead, so you can have a common interface for
210
+ your observable object. This will add the `.call()` method to the target class,
211
+ which will delegate attributes to the observable's `initialize` method and call
212
+ its `call` method.
201
213
 
202
214
  ```ruby
203
215
  class Contact
@@ -219,7 +231,43 @@ Contact.call('John', 'john@example.com') do |o|
219
231
  end
220
232
  ```
221
233
 
222
- Notice that you don't have to explicit call the instance's `call` method; `Contact.call` will initialize the object with all the provided parameters and call `Contact#call` after the block has been executed.
234
+ Notice that you don't have to explicit call the instance's `call` method;
235
+ `Contact.call` will initialize the object with all the provided parameters and
236
+ call `Contact#call` after the block has been executed.
237
+
238
+ ### Testing
239
+
240
+ `Signal::Mock` can be helpful for most test situations where you don't want to
241
+ bring other mock libraries.
242
+
243
+ ```ruby
244
+ require "signal/mock"
245
+
246
+ class SomeTest < Minitest::Test
247
+ def test_some_test
248
+ mock = Signal::Mock.new
249
+
250
+ # Using listener
251
+ sum = Sum.new
252
+ sum.add_listener(mock)
253
+
254
+ # Calling `mock.on(event_name)` is required because
255
+ # the handler doesn't receive the event name, just the
256
+ # arguments.
257
+ sum = Sum.new
258
+ sum.on(:result, &mock.on(:result))
259
+
260
+ # Using with Signal.call
261
+ Sum.call(1, 2, &mock)
262
+
263
+ assert mock.received?(:result)
264
+ assert mock.received?(:result, times: 1)
265
+ assert mock.received?(:result, with: [3])
266
+ assert mock.received?(:result, with: ->(result) { result == 3 } )
267
+ end
268
+ end
269
+
270
+ ```
223
271
 
224
272
  ## Contributing
225
273
 
@@ -231,25 +279,23 @@ Notice that you don't have to explicit call the instance's `call` method; `Conta
231
279
 
232
280
  ## License
233
281
 
234
- Copyright (c) 2013-2015 Nando Vieira
282
+ Copyright (c) 2013 Nando Vieira
235
283
 
236
284
  MIT License
237
285
 
238
- Permission is hereby granted, free of charge, to any person obtaining
239
- a copy of this software and associated documentation files (the
240
- "Software"), to deal in the Software without restriction, including
241
- without limitation the rights to use, copy, modify, merge, publish,
242
- distribute, sub-license, and/or sell copies of the Software, and to
243
- permit persons to whom the Software is furnished to do so, subject to
244
- the following conditions:
245
-
246
- The above copyright notice and this permission notice shall be
247
- included in all copies or substantial portions of the Software.
248
-
249
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
250
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
251
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
252
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
253
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
254
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
255
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
286
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
287
+ this software and associated documentation files (the "Software"), to deal in
288
+ the Software without restriction, including without limitation the rights to
289
+ use, copy, modify, merge, publish, distribute, sub-license, and/or sell copies
290
+ of the Software, and to permit persons to whom the Software is furnished to do
291
+ so, subject to the following conditions:
292
+
293
+ The above copyright notice and this permission notice shall be included in all
294
+ copies or substantial portions of the Software.
295
+
296
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
297
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
298
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
299
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
300
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
301
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1 +1,15 @@
1
- require 'bundler/gem_tasks'
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+ require "rubocop/rake_task"
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.libs << "test"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ t.warning = false
11
+ end
12
+
13
+ RuboCop::RakeTask.new
14
+
15
+ task default: %i[test rubocop]
@@ -1,13 +1,15 @@
1
- $:.unshift File.expand_path('../../lib', __FILE__)
2
- require 'signal'
3
- require 'active_record'
1
+ # frozen_string_literal: true
4
2
 
5
- ActiveRecord::Base.establish_connection({
6
- :adapter => 'sqlite3',
7
- :database => ':memory:'
8
- })
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
5
+ require "active_record"
9
6
 
10
- ActiveRecord::Schema.define(:version => 0) do
7
+ ActiveRecord::Base.establish_connection(
8
+ adapter: "sqlite3",
9
+ database: ":memory:"
10
+ )
11
+
12
+ ActiveRecord::Schema.define(version: 0) do
11
13
  create_table :things do |t|
12
14
  t.string :name
13
15
  t.timestamps null: false
@@ -20,7 +22,7 @@ class Thing < ActiveRecord::Base
20
22
  validates_presence_of :name
21
23
  end
22
24
 
23
- thing = Thing.new(:name => 'Stuff')
25
+ thing = Thing.new(name: "Stuff")
24
26
  thing.on(:create) {|model| puts model.updated_at, model.name }
25
27
  thing.on(:update) {|model| puts model.updated_at, model.name }
26
28
  thing.on(:remove) {|model| puts model.destroyed? }
@@ -30,12 +32,12 @@ thing.save!
30
32
  #=> 2013-01-26 10:32:39 -0200
31
33
  #=> Stuff
32
34
 
33
- thing.update_attributes(:name => 'Updated stuff')
35
+ thing.update_attributes(name: "Updated stuff")
34
36
  #=> 2013-01-26 10:33:11 -0200
35
37
  #=> Updated stuff
36
38
 
37
- thing.update_attributes(:name => nil)
38
- #=> ['Name can't be blank']
39
+ thing.update_attributes(name: nil)
40
+ #=> ["Name can"t be blank"]
39
41
 
40
42
  thing.destroy
41
43
  #=> true
@@ -1,5 +1,7 @@
1
- $:.unshift File.expand_path('../../lib', __FILE__)
2
- require 'signal'
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
3
5
 
4
6
  class Arguments
5
7
  include Signal
@@ -1,5 +1,7 @@
1
- $:.unshift File.expand_path('../../lib', __FILE__)
2
- require 'signal'
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
3
5
 
4
6
  class Contact
5
7
  include Signal
@@ -7,7 +9,8 @@ class Contact
7
9
  attr_reader :name, :email
8
10
 
9
11
  def initialize(name, email)
10
- @name, @email = name, email
12
+ @name = name
13
+ @email = email
11
14
  end
12
15
 
13
16
  def output!
@@ -15,6 +18,6 @@ class Contact
15
18
  end
16
19
  end
17
20
 
18
- contact = Contact.new('John Doe', 'john@example.org')
19
- contact.on(:output) {|contact| puts contact.name, contact.email }
21
+ contact = Contact.new("John Doe", "john@example.org")
22
+ contact.on(:output) {|c| puts c.name, c.email }
20
23
  contact.output!
data/examples/blocks.rb CHANGED
@@ -1,5 +1,7 @@
1
- $:.unshift File.expand_path('../../lib', __FILE__)
2
- require 'signal'
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
3
5
 
4
6
  class Status
5
7
  include Signal
@@ -10,7 +12,7 @@ class Status
10
12
  end
11
13
 
12
14
  status = Status.new
13
- status.before(:ready) { puts 'Before the ready event!' }
15
+ status.before(:ready) { puts "Before the ready event!" }
14
16
  status.on(:ready) { puts "I'm ready!" }
15
- status.after(:ready) { puts 'After the ready event!' }
17
+ status.after(:ready) { puts "After the ready event!" }
16
18
  status.ready!
data/examples/call.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
5
+
6
+ class Contact
7
+ include Signal.call
8
+
9
+ attr_reader :name, :email
10
+
11
+ def initialize(name, email)
12
+ @name = name
13
+ @email = email
14
+ end
15
+
16
+ def call
17
+ emit(:output, self)
18
+ end
19
+ end
20
+
21
+ Contact.call("John", "john@example.com") do |o|
22
+ o.on(:output) {|contact| puts contact.name }
23
+ end
data/examples/chain.rb CHANGED
@@ -1,13 +1,15 @@
1
- $:.unshift File.expand_path('../../lib', __FILE__)
2
- require 'signal'
3
- require 'active_record'
1
+ # frozen_string_literal: true
4
2
 
5
- ActiveRecord::Base.establish_connection({
6
- :adapter => 'sqlite3',
7
- :database => ':memory:'
8
- })
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
5
+ require "active_record"
9
6
 
10
- ActiveRecord::Schema.define(:version => 0) do
7
+ ActiveRecord::Base.establish_connection(
8
+ adapter: "sqlite3",
9
+ database: ":memory:"
10
+ )
11
+
12
+ ActiveRecord::Schema.define(version: 0) do
11
13
  create_table :things do |t|
12
14
  t.string :name
13
15
  t.timestamps null: false
@@ -15,14 +17,14 @@ ActiveRecord::Schema.define(:version => 0) do
15
17
  end
16
18
 
17
19
  class Thing < ActiveRecord::Base
18
- include Signal::ActiveRecord
20
+ include Signal.active_record
19
21
 
20
22
  validates_presence_of :name
21
23
  end
22
24
 
23
25
  class MyListener
24
- [:validation, :update, :create, :remove].each do |type|
25
- class_eval <<-RUBY
26
+ %i[validation update create remove].each do |type|
27
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
26
28
  def before_#{type}(thing); puts __method__; end
27
29
  def on_#{type}(thing); puts __method__; end
28
30
  def after_#{type}(thing); puts __method__; end
@@ -31,26 +33,26 @@ class MyListener
31
33
  end
32
34
 
33
35
  puts "\n=== Creating valid record"
34
- thing = Thing.new(:name => 'Stuff')
36
+ thing = Thing.new(name: "Stuff")
35
37
  thing.listeners << MyListener.new
36
38
  thing.save
37
39
 
38
40
  puts "\n=== Creating invalid record"
39
- thing = Thing.new(:name => nil)
41
+ thing = Thing.new(name: nil)
40
42
  thing.listeners << MyListener.new
41
43
  thing.save
42
44
 
43
45
  puts "\n=== Updating valid record"
44
- thing = Thing.create(:name => 'Stuff')
46
+ thing = Thing.create(name: "Stuff")
45
47
  thing.listeners << MyListener.new
46
- thing.update_attributes(:name => 'Updated stuff')
48
+ thing.update_attributes(name: "Updated stuff")
47
49
 
48
50
  puts "\n=== Updating invalid record"
49
- thing = Thing.create!(:name => 'Stuff')
51
+ thing = Thing.create!(name: "Stuff")
50
52
  thing.listeners << MyListener.new
51
- thing.update_attributes(:name => nil)
53
+ thing.update_attributes(name: nil)
52
54
 
53
55
  puts "\n=== Removing record"
54
- thing = Thing.create(:name => 'Stuff')
56
+ thing = Thing.create(name: "Stuff")
55
57
  thing.listeners << MyListener.new
56
58
  thing.destroy
data/examples/listener.rb CHANGED
@@ -1,5 +1,7 @@
1
- $:.unshift File.expand_path('../../lib', __FILE__)
2
- require 'signal'
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
4
+ require "signal"
3
5
 
4
6
  class Status
5
7
  include Signal
@@ -11,7 +13,7 @@ end
11
13
 
12
14
  class MyListener
13
15
  def before_ready
14
- puts 'Before the ready event!'
16
+ puts "Before the ready event!"
15
17
  end
16
18
 
17
19
  def on_ready
@@ -19,7 +21,7 @@ class MyListener
19
21
  end
20
22
 
21
23
  def after_ready
22
- puts 'After the ready event!'
24
+ puts "After the ready event!"
23
25
  end
24
26
  end
25
27
 
@@ -1,29 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Signal
2
- module ActiveRecord
3
- def self.included(base)
4
- base.class_eval do
5
- include Signal
6
- include InstanceMethods
7
-
8
- around_create :around_create_signal
9
- around_save :around_save_signal
10
- around_destroy :around_destroy_signal
11
- before_validation :before_validation_signal
12
- after_validation :after_validation_signal
4
+ def self.active_record
5
+ Extensions::ActiveRecord
6
+ end
7
+
8
+ module Extensions
9
+ module ActiveRecord
10
+ def self.included(base)
11
+ base.class_eval do
12
+ include Signal
13
+
14
+ around_create :around_create_signal
15
+ around_save :around_save_signal
16
+ around_destroy :around_destroy_signal
17
+ before_validation :before_validation_signal
18
+ after_validation :after_validation_signal
19
+ end
13
20
  end
14
- end
15
21
 
16
- module InstanceMethods
17
- private
18
- def around_create_signal
22
+ private def around_create_signal
19
23
  emit_signal(:before, :create, self)
20
24
  yield
21
25
  return unless persisted?
26
+
22
27
  emit_signal(:on, :create, self)
23
28
  emit_signal(:after, :create, self)
24
29
  end
25
30
 
26
- def around_save_signal
31
+ private def around_save_signal
27
32
  if new_record?
28
33
  yield
29
34
  return
@@ -35,18 +40,18 @@ module Signal
35
40
  emit_signal(:after, :update, self)
36
41
  end
37
42
 
38
- def around_destroy_signal
43
+ private def around_destroy_signal
39
44
  emit_signal(:before, :remove, self)
40
45
  yield
41
46
  emit_signal(:on, :remove, self)
42
47
  emit_signal(:after, :remove, self)
43
48
  end
44
49
 
45
- def before_validation_signal
50
+ private def before_validation_signal
46
51
  emit_signal(:before, :validation, self)
47
52
  end
48
53
 
49
- def after_validation_signal
54
+ private def after_validation_signal
50
55
  emit_signal(:on, :validation, self) if errors.any?
51
56
  emit_signal(:after, :validation, self)
52
57
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Signal
4
+ def self.call
5
+ Extensions::Call
6
+ end
7
+
8
+ module Extensions
9
+ module Call
10
+ def self.included(target)
11
+ target.include(Signal)
12
+ target.extend(ClassMethods)
13
+ end
14
+
15
+ module ClassMethods
16
+ def call(*args, **kwargs)
17
+ new(*args, **kwargs).tap do |instance|
18
+ yield(instance) if block_given?
19
+ instance.call
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Signal
2
4
  class Listener
3
5
  def initialize(context, type, event, &block)
@@ -10,6 +12,7 @@ module Signal
10
12
 
11
13
  def method_missing(method_name, *args)
12
14
  return super unless respond_to_missing?(method_name, false)
15
+
13
16
  @block.call(*args)
14
17
  end
15
18
 
@@ -17,7 +20,7 @@ module Signal
17
20
  "<#{self.class} event: #{@event_method}>"
18
21
  end
19
22
 
20
- def respond_to_missing?(method_name, include_private)
23
+ def respond_to_missing?(method_name, _include_private)
21
24
  method_name == @event_method
22
25
  end
23
26
  end