u-observers 0.1.0 → 0.6.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
  SHA256:
3
- metadata.gz: 5b6af97772fa9dd076bce666422332213179f338466d8be317fa7d324fc82c84
4
- data.tar.gz: 133d22595bb0ad4dc70c7b6d2be2481f2dc0522acf7bddc7d015cd2141362f63
3
+ metadata.gz: ee142231055e893f34d726e7bbf57b5fd27da851e49c63a5a33a3dcf6a000abe
4
+ data.tar.gz: 5ca62a10c247a02435622b8190114f45c8e28be50f9a5e8e8dd5f21c42a99c2c
5
5
  SHA512:
6
- metadata.gz: 775bc25517f90cea5b657ae9753a025796ba7091062033b515b3311b390f126315db16fb7732763f3b618cc0df4ae9430d211740f6dce1a8733eabee73fa9214
7
- data.tar.gz: 29ab84f8b07117108c431c05810727532afd63e42c88cc8c6799e4e6efb7c12ef40ddc8f1e8c526d23326cbd9a6792b2de1853d7121ee2abe2c45fe0f95ad3d1
6
+ metadata.gz: c8bb160a235375a6a99c2c379413b79952ac85492211feb08dc77e0435e7e87aef3edc5c68bed81b16364a5197615321ea3a894c6bbad9143c831fb63f781fdd
7
+ data.tar.gz: c861884ac244f036a9ab78edce25cf857fed41afcf18467354dd784e27728921b3a6c61695cbbf86ae3d0bef2ad71a2364e84bed2d9b6f6f33d27bae810ab0cf
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+
10
+ Gemfile.lock
@@ -2,27 +2,31 @@ require 'micro/observers/version'
2
2
 
3
3
  module Micro
4
4
  module Observers
5
+ require 'micro/observers/utils'
6
+ require 'micro/observers/events_or_actions'
5
7
  require 'micro/observers/manager'
6
8
 
7
9
  module ClassMethods
8
- def call_observers(with: :call)
9
- proc do |object|
10
- Array(with)
11
- .each { |action| object.observers.call(object, action: action) }
12
- end
10
+ def notify_observers!(with:)
11
+ proc { |object| with.each { |evt_or_act| object.observers.notify(evt_or_act) } }
13
12
  end
14
13
 
15
- def notify_observers(with: :call)
16
- call_observers(with: with)
14
+ def notify_observers(*events)
15
+ notify_observers!(with: EventsOrActions[events])
16
+ end
17
+
18
+ def call_observers(options = Utils::EMPTY_HASH)
19
+ notify_observers!(with: EventsOrActions.fetch_actions(options))
17
20
  end
18
21
  end
19
22
 
20
23
  def self.included(base)
21
24
  base.extend(ClassMethods)
25
+ base.send(:private_class_method, :notify_observers!)
22
26
  end
23
27
 
24
28
  def observers
25
- @observers ||= Observers::Manager.new
29
+ @observers ||= Observers::Manager.for(self)
26
30
  end
27
31
 
28
32
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module EventsOrActions
7
+ DEFAULTS = [:call]
8
+
9
+ def self.[](value)
10
+ values = Utils.compact_array(value)
11
+
12
+ values.empty? ? DEFAULTS : values
13
+ end
14
+
15
+ def self.fetch_actions(hash)
16
+ return self[hash.fetch(:actions) { hash.fetch(:action) }] if hash.is_a?(Hash)
17
+
18
+ raise ArgumentError, 'expected a hash with the key :action or :actions'
19
+ end
20
+
21
+ private_constant :DEFAULTS
22
+ end
23
+
24
+ end
25
+ end
@@ -4,45 +4,83 @@ module Micro
4
4
  module Observers
5
5
 
6
6
  class Manager
7
- EMPTY_HASH = {}.freeze
7
+ EqualTo = -> (observer) do
8
+ -> item { item[0] == :observer && item[1] == observer }
9
+ end
10
+
11
+ def self.for(subject)
12
+ new(subject)
13
+ end
14
+
15
+ def initialize(subject, list = nil)
16
+ @subject = subject
17
+
18
+ @list = Utils.compact_array(list.kind_of?(Array) ? list : [])
19
+ end
8
20
 
9
- def initialize(list = nil)
10
- @list = (list.kind_of?(Array) ? list : []).flatten.tap(&:compact!)
21
+ def included?(observer)
22
+ @list.any?(&EqualTo[observer])
11
23
  end
12
24
 
13
- def attach(observer, options = EMPTY_HASH)
14
- if options[:allow_duplication] || @list.none? { |obs, _data| obs == observer }
15
- @list << [observer, options[:data]]
25
+ def attach(observer, options = Utils::EMPTY_HASH)
26
+ if options[:allow_duplication] || !included?(observer)
27
+ @list << [:observer, observer, options[:data]]
16
28
  end
17
29
 
18
30
  self
19
31
  end
20
32
 
33
+ def on(options = Utils::EMPTY_HASH)
34
+ event, callable, with = options[:event], options[:call], options[:with]
35
+
36
+ return self unless event.is_a?(Symbol) && callable.respond_to?(:call)
37
+
38
+ arg = with.is_a?(Proc) ? with.call(@subject) : (arg || subject)
39
+
40
+ @list << [:callable, event, [callable, arg]]
41
+ end
42
+
21
43
  def detach(observer)
22
- @list.delete_if { |obs, _data| obs == observer }
44
+ @list.delete_if(&EqualTo[observer])
45
+
46
+ self
47
+ end
48
+
49
+ def notify(*events)
50
+ broadcast(EventsOrActions[events])
23
51
 
24
52
  self
25
53
  end
26
54
 
27
- def call(subject, action: :call)
28
- @list.each do |observer, data|
29
- next unless observer.respond_to?(action)
55
+ def call(options = Utils::EMPTY_HASH)
56
+ broadcast(EventsOrActions.fetch_actions(options))
57
+
58
+ self
59
+ end
30
60
 
31
- handler = observer.method(action)
61
+ private
32
62
 
33
- case handler.arity
34
- when 2 then handler.call(subject, data)
35
- when 1 then handler.call(subject)
36
- else raise NotImplementedError
63
+ def broadcast(evts_or_acts)
64
+ evts_or_acts.each do |evt_or_act|
65
+ @list.each do |strategy, observer, data|
66
+ call!(observer, strategy, data, with: evt_or_act)
67
+ end
37
68
  end
38
69
  end
39
70
 
40
- self
41
- end
71
+ def call!(observer, strategy, data, with:)
72
+ return data[0].call(data[1]) if strategy == :callable && observer == with
73
+
74
+ if strategy == :observer && observer.respond_to?(with)
75
+ handler = observer.method(with)
42
76
 
43
- alias notify call
77
+ return handler.call(@subject) if handler.arity == 1
78
+
79
+ handler.call(@subject, data)
80
+ end
81
+ end
44
82
 
45
- private_constant :EMPTY_HASH
83
+ private_constant :EqualTo
46
84
  end
47
85
 
48
86
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Micro
4
+ module Observers
5
+
6
+ module Utils
7
+ EMPTY_HASH = {}.freeze
8
+
9
+ def self.compact_array(value)
10
+ Array(value).flatten.tap(&:compact!)
11
+ end
12
+ end
13
+
14
+ end
15
+ end
@@ -1,5 +1,5 @@
1
1
  module Micro
2
2
  module Observers
3
- VERSION = '0.1.0'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: u-observers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Serradura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-25 00:00:00.000000000 Z
11
+ date: 2020-09-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple and powerful implementation of the observer pattern.
14
14
  email:
@@ -21,14 +21,15 @@ files:
21
21
  - ".travis.yml"
22
22
  - CODE_OF_CONDUCT.md
23
23
  - Gemfile
24
- - Gemfile.lock
25
24
  - LICENSE.txt
26
25
  - README.md
27
26
  - Rakefile
28
27
  - bin/console
29
28
  - bin/setup
30
29
  - lib/micro/observers.rb
30
+ - lib/micro/observers/events_or_actions.rb
31
31
  - lib/micro/observers/manager.rb
32
+ - lib/micro/observers/utils.rb
32
33
  - lib/micro/observers/version.rb
33
34
  - lib/u-observers.rb
34
35
  - u-observers.gemspec
@@ -1,48 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- u-observers (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activemodel (6.0.3.3)
10
- activesupport (= 6.0.3.3)
11
- activerecord (6.0.3.3)
12
- activemodel (= 6.0.3.3)
13
- activesupport (= 6.0.3.3)
14
- activesupport (6.0.3.3)
15
- concurrent-ruby (~> 1.0, >= 1.0.2)
16
- i18n (>= 0.7, < 2)
17
- minitest (~> 5.1)
18
- tzinfo (~> 1.1)
19
- zeitwerk (~> 2.2, >= 2.2.2)
20
- concurrent-ruby (1.1.7)
21
- docile (1.3.2)
22
- i18n (1.8.5)
23
- concurrent-ruby (~> 1.0)
24
- minitest (5.14.2)
25
- rake (12.3.3)
26
- simplecov (0.19.0)
27
- docile (~> 1.1)
28
- simplecov-html (~> 0.11)
29
- simplecov-html (0.12.2)
30
- sqlite3 (1.4.2)
31
- thread_safe (0.3.6)
32
- tzinfo (1.2.7)
33
- thread_safe (~> 0.1)
34
- zeitwerk (2.4.0)
35
-
36
- PLATFORMS
37
- ruby
38
-
39
- DEPENDENCIES
40
- activerecord
41
- minitest (~> 5.0)
42
- rake (~> 12.0)
43
- simplecov (~> 0.19)
44
- sqlite3
45
- u-observers!
46
-
47
- BUNDLED WITH
48
- 2.1.4