emittance 0.0.2 → 0.0.3

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.
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emittance
4
+ module Helpers
5
+ ##
6
+ # Some helpers for fetching, setting, and manipulating constants.
7
+ #
8
+ module ConstantHelpers
9
+ # Since +Object.const_set+ does not support namespaced constant names, use this to set the constant to the
10
+ # correct namespace.
11
+ #
12
+ # Example:
13
+ #
14
+ # my_const_name = 'String::Foo'
15
+ # Object.const_set my_const_name, 'bar'
16
+ # # => NameError: wrong constant name String::Foo
17
+ #
18
+ # set_namespaced_constant_by_name my_const_name, 'bar'
19
+ # String::Foo
20
+ # # => 'bar'
21
+ #
22
+ # @param const_name [String] a valid namespaced constant name
23
+ # @param obj the value you wish to set that constant to
24
+ def set_namespaced_constant_by_name(const_name, obj)
25
+ names = const_name.split('::')
26
+ names.shift if names.size > 1 && names.first.empty?
27
+
28
+ namespace = names.size == 1 ? Object : Object.const_get(names[0...-1].join('::'))
29
+ namespace.const_set names.last, obj
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Emittance
4
+ module Helpers
5
+ ##
6
+ # Some helper methods to mix in for the purposes of manipulating strings.
7
+ #
8
+ module StringHelpers
9
+ # Snake case the string, like Rails' +String#underscore+ method. As such, strings that look like namespaced
10
+ # constants will have the namespace resolver operators replaced with +/+ characters, rather than underscores.
11
+ # For example: +'Foo::BarBaz'+ becomes +'foo/bar_baz'+.
12
+ #
13
+ # @param str [String] the string you wish to convert
14
+ # @return [String] a new string that is the snake-cased version of the old string
15
+ def snake_case(str)
16
+ str.gsub(/::/, '/')
17
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
18
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
19
+ .tr('-', '_')
20
+ .downcase
21
+ end
22
+
23
+ # Camel case the string, like Rails' +String#classify+ method. This essentially works like the inverse of
24
+ # +snake_case+, so +'foo/bar_baz'+ becomes +'Foo::BarBaz'+. There is one one notable exception:
25
+ #
26
+ # camel_case(snake_case('APIFoo'))
27
+ # # => 'ApiFoo'
28
+ #
29
+ # As such, be mindful when naming your classes.
30
+ #
31
+ # @param str [String] the string you wish to convert
32
+ # @return [String] a new string converted to camel case.
33
+ def camel_case(str)
34
+ str = str.sub(/^[a-z\d]*/) { $&.capitalize }
35
+ str = str.gsub(%r{(?:_|(\/))([a-z\d]*)}) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }
36
+ str.gsub(%r{\/}, '::')
37
+ end
38
+
39
+ # Strip all characters that can't go into a constant name.
40
+ #
41
+ # @param str [String] the string from which you want to remove punctuation
42
+ # @return [String] a new string with punctuation stripped
43
+ def clean_up_punctuation(str)
44
+ str.gsub(%r{[^A-Za-z\d\_\:\/]}, '')
45
+ end
46
+ end
47
+ end
48
+ end
@@ -3,10 +3,10 @@
3
3
  module Emittance
4
4
  # @private
5
5
  class Registration
6
- attr_reader :identifier
6
+ attr_reader :event_klass
7
7
 
8
- def initialize(identifier, &callback)
9
- @identifier = identifier
8
+ def initialize(event_klass, &callback)
9
+ @event_klass = event_klass
10
10
  @callback = callback
11
11
  end
12
12
 
@@ -1,5 +1,5 @@
1
- # froze_string_literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Emittance
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
@@ -1,7 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Emittance
4
+ ##
5
+ # Can watch for events that propagate through the system.
6
+ #
4
7
  module Watcher
8
+ # Watch for an event, identified by its class' identifier. If a callback method is provided, then it will call that
9
+ # method on the caller of +watch+ when the event happens. Otherwise, it will run the callback block.
10
+ #
11
+ # @param identifier [Symbol] the event's identifier
12
+ # @param callback_method [Symbol] one option for adding a callback--the method on the object to call when the
13
+ # event fires
14
+ # @param callback [Block] the other option for adding a callback--the block you wish to be executed when the event
15
+ # fires
16
+ # @return [Proc] the block that will run when the event fires
5
17
  def watch(identifier, callback_method = nil, &callback)
6
18
  if callback_method
7
19
  Emittance::Dispatcher.register_method_call identifier, self, callback_method
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emittance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Guillen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-05 00:00:00.000000000 Z
11
+ date: 2017-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,49 +25,49 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.15'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: pry
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: '10.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: '10.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '3.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: yard
70
+ name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: simplecov
84
+ name: yard
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -124,11 +124,12 @@ files:
124
124
  - lib/emittance/emitter.rb
125
125
  - lib/emittance/errors.rb
126
126
  - lib/emittance/event.rb
127
- - lib/emittance/event/event_builder.rb
127
+ - lib/emittance/event_lookup.rb
128
+ - lib/emittance/helpers/constant_helpers.rb
129
+ - lib/emittance/helpers/string_helpers.rb
128
130
  - lib/emittance/registration.rb
129
131
  - lib/emittance/version.rb
130
132
  - lib/emittance/watcher.rb
131
- - pkg/emittance-0.0.1.gem
132
133
  homepage: https://github.com/aastronautss/emittance
133
134
  licenses:
134
135
  - MIT
@@ -1,154 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Emittance
4
- # @private
5
- class Event
6
- class EventBuilder
7
- KLASS_NAME_SUFFIX = 'Event'
8
-
9
- class << self
10
- def klass_exists_for_identifier?(identifier)
11
- klass_name = generate_event_klass_name identifier
12
- !!lookup_event_klass(klass_name)
13
- end
14
-
15
- def objects_to_klass(*objs)
16
- klass = nil
17
-
18
- klass ||= pass_klass_through(*objs)
19
- klass ||= find_by_custom_identifier(*objs)
20
- klass ||= generate_event_klass(*objs)
21
-
22
- klass
23
- end
24
-
25
- def klass_to_identifier(klass)
26
- identifier = nil
27
-
28
- identifier ||= reverse_find_by_custom_identifier(klass)
29
- identifier ||= convert_klass_to_identifier(klass)
30
-
31
- identifier
32
- end
33
-
34
- def register_custom_identifier(klass, identifier)
35
- CustomIdentifiers.set identifier, klass
36
- end
37
-
38
- private
39
-
40
- def pass_klass_through(*objs)
41
- objs.length == 1 && objs[0].is_a?(Class) && objs[0] < Emittance::Event ? objs[0] : nil
42
- end
43
-
44
- def find_by_custom_identifier(*objs)
45
- if objs.length == 1
46
- CustomIdentifiers.event_klass_for objs[0]
47
- else
48
- nil
49
- end
50
- end
51
-
52
- def reverse_find_by_custom_identifier(klass)
53
- CustomIdentifiers.identifier_for klass
54
- end
55
-
56
- def generate_event_klass_name(*objs)
57
- klass_name_parts = objs.map { |obj| klassable_name_for obj }
58
- dress_up_klass_name klass_name_parts
59
- end
60
-
61
- def generate_event_klass(*objs)
62
- klass_name = generate_event_klass_name(*objs)
63
- find_or_create_event_klass klass_name
64
- end
65
-
66
- def convert_klass_to_identifier(klass)
67
- identifier_str = klass.name
68
- identifier_str = undress_klass_name identifier_str
69
- identifier_str = snake_case identifier_str
70
-
71
- identifier_str.to_sym
72
- end
73
-
74
- def klassable_name_for(obj)
75
- name_str = obj.to_s
76
- name_str = camel_case name_str
77
- name_str = clean_up_punctuation name_str
78
-
79
- name_str
80
- end
81
-
82
- def camel_case(str)
83
- str = str.sub(/^[a-z\d]*/) { $&.capitalize }
84
- str.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }
85
- end
86
-
87
- def snake_case(str)
88
- str.gsub(/::/, '_')
89
- .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
90
- .gsub(/([a-z\d])([A-Z])/,'\1_\2')
91
- .tr("-", "_")
92
- .downcase
93
- end
94
-
95
- def clean_up_punctuation(str)
96
- str.gsub /[^A-Za-z\d]/, ''
97
- end
98
-
99
- def dress_up_klass_name(klass_name_parts)
100
- "#{Array(klass_name_parts).join}#{KLASS_NAME_SUFFIX}"
101
- end
102
-
103
- def undress_klass_name(klass_name_str)
104
- klass_name_str.gsub /#{KLASS_NAME_SUFFIX}$/, ''
105
- end
106
-
107
- def lookup_event_klass(klass_name)
108
- if Object.const_defined? klass_name
109
- Object.const_get klass_name
110
- else
111
- nil
112
- end
113
- end
114
-
115
- def find_or_create_event_klass(klass_name)
116
- lookup_event_klass(klass_name) || create_event_klass(klass_name)
117
- end
118
-
119
- def create_event_klass(klass_name)
120
- new_klass = Class.new(Emittance::Event)
121
- Object.const_set klass_name, new_klass
122
- end
123
- end
124
-
125
- class CustomIdentifiers
126
- @mappings = {}
127
-
128
- class << self
129
- def mapping_exists?(identifier)
130
- !!mappings[identifier] || Emittance::Event::EventBuilder.klass_exists_for_identifier?(identifier)
131
- end
132
-
133
- def event_klass_for(identifier)
134
- mappings[identifier]
135
- end
136
-
137
- def identifier_for(event_klass)
138
- mappings.key event_klass
139
- end
140
-
141
- def set(identifier, event_klass)
142
- raise Emittance::InvalidIdentifierError, 'Event identifiers must be a Symbol.' unless identifier.is_a? Symbol
143
- raise Emittance::IdentifierTakenError if mapping_exists? identifier
144
- mappings[identifier] = event_klass
145
- end
146
-
147
- private
148
-
149
- attr_reader :mappings
150
- end
151
- end
152
- end
153
- end
154
- end
Binary file