emittance 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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