hoodie 0.4.2 → 0.4.3

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
  SHA1:
3
- metadata.gz: 3f049115fb6e28197cf8fc99f90a93b47dfc6d36
4
- data.tar.gz: 11356e662f4b076be57c3b42f5e0f0f37ceba367
3
+ metadata.gz: 63d0ae0f7b0c7af6c0e944764423870c80291599
4
+ data.tar.gz: ed2ae198e58ac097ccc090b31e52f2b96fa21d78
5
5
  SHA512:
6
- metadata.gz: b7655a46f873e0a0bcaa29b190086e05782816696cbf8d59d013547c32a98d99486fc85d3a773da46655315a26e4cab78a2f4eb22a570f3cb6897d9f8a2bab65
7
- data.tar.gz: f4d66b616e2e3f5a73adb2f1dd22b201be54f49c9d8bc43126bb9498333e018f4a75795c6cb25fe739c15bdc853deb5b1757610b9340594eaaa832ebec485c1e
6
+ metadata.gz: 429be0f60bf5cd785c4244a55311f55ae6994c8d7a424b45a41646c9afe83c2eaf989c7cb70156b7ce2d4d4e3e8c20785815227065731431591689cdeee998c3
7
+ data.tar.gz: 1ab5e7087209dd755964abe345b3144c66a213160c7032290e445e7c8662cf9a946b5700d95466642dde0133b7612e7ce26452e9ab31639273b07459ee679e7c
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2014 Stefano Harding
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
4
  require 'rubocop/rake_task'
5
+ require 'yard'
5
6
 
6
7
  desc 'Run tests'
7
8
  RSpec::Core::RakeTask.new(:spec)
@@ -12,4 +13,14 @@ RuboCop::RakeTask.new(:rubocop) do |task|
12
13
  task.fail_on_error = true
13
14
  end
14
15
 
15
- task default: [:spec, :rubocop, :build, :install]
16
+ YARD::Config.load_plugin 'redcarpet-ext'
17
+ YARD::Rake::YardocTask.new do |t|
18
+ additional_docs = %w[ CHANGELOG.md LICENSE.md README.md ]
19
+ t.files = ['lib/*.rb', '-'] + additional_docs
20
+ t.options = ['--readme=README.md', '--markup=markdown', '--verbose']
21
+ end
22
+
23
+ desc 'Build documentation'
24
+ task doc: [:yard]
25
+
26
+ task default: [:spec, :rubocop, :doc, :build, :install]
data/hoodie.gemspec CHANGED
@@ -22,10 +22,10 @@ Gem::Specification.new do |s|
22
22
  # s.add_runtime_dependency 'anemone', '>= 0.7.2'
23
23
  s.add_runtime_dependency 'hitimes'
24
24
 
25
- s.add_development_dependency 'rubocop', '~> 0.26.0'
26
- s.add_development_dependency 'rake', '~> 10.3.2'
27
- s.add_development_dependency 'coveralls', '~> 0.7.1'
28
- s.add_development_dependency 'rspec', '~> 3.1.0'
29
- s.add_development_dependency 'fuubar', '~> 2.0.0'
30
- s.add_development_dependency 'timecop', '~> 0.7.1'
25
+ s.add_development_dependency 'rubocop', '>= 0.26.0'
26
+ s.add_development_dependency 'rake', '>= 10.3.2'
27
+ s.add_development_dependency 'coveralls', '>= 0.7.1'
28
+ s.add_development_dependency 'rspec', '>= 3.1.0'
29
+ s.add_development_dependency 'fuubar', '>= 2.0.0'
30
+ s.add_development_dependency 'timecop', '>= 0.7.1'
31
31
  end
data/lib/hoodie/hash.rb CHANGED
@@ -110,32 +110,6 @@ class Hash
110
110
  recursively_transform_keys { |key| key.to_s rescue key }
111
111
  end
112
112
 
113
- class UndefinedPathError < StandardError; end
114
- # Recursively searchs a nested datastructure for a key and returns
115
- # the value. If a block is provided its value will be returned if
116
- # the key does not exist
117
- #
118
- # @example
119
- # options = { server: { location: { row: { rack: 34 } } } }
120
- # options.recursive_fetch :server, :location, :row, :rack
121
- # # => 34
122
- # options.recursive_fetch(:non_existent_key) { 'default' }
123
- # # => "default"
124
- #
125
- # @return [Hash, Array, String] value for key
126
- #
127
- def recursive_fetch(*args, &block)
128
- args.reduce(self) do |obj, arg|
129
- begin
130
- arg = Integer(arg) if obj.is_a? Array
131
- obj.fetch(arg)
132
- rescue ArgumentError, IndexError, NoMethodError => e
133
- break block.call(arg) if block
134
- raise UndefinedPathError, "Could not fetch path (#{args.join(' > ')}) at #{arg}", e.backtrace
135
- end
136
- end
137
- end
138
-
139
113
  def recursive_merge(other)
140
114
  hash = dup
141
115
  other.each do |key, value|
@@ -0,0 +1,309 @@
1
+
2
+ module Garcon
3
+ module Observable
4
+
5
+ # @return [Object] the added observer
6
+ #
7
+ def add_observer(*args, &block)
8
+ observers.add_observer(*args, &block)
9
+ end
10
+
11
+ # as #add_observer but it can be used for chaining
12
+ #
13
+ # @return [Observable] self
14
+ #
15
+ def with_observer(*args, &block)
16
+ add_observer(*args, &block)
17
+ self
18
+ end
19
+
20
+ # @return [Object] the deleted observer
21
+ #
22
+ def delete_observer(*args)
23
+ observers.delete_observer(*args)
24
+ end
25
+
26
+ # @return [Observable] self
27
+ #
28
+ def delete_observers
29
+ observers.delete_observers
30
+ self
31
+ end
32
+
33
+ # @return [Integer] the observers count
34
+ #
35
+ def count_observers
36
+ observers.count_observers
37
+ end
38
+
39
+ protected # A T T E N Z I O N E A R E A P R O T E T T A
40
+
41
+ attr_accessor :observers
42
+ end
43
+
44
+ # A thread safe observer set implemented using copy-on-read approach.
45
+ # Observers are added and removed from a thread safe collection; every time
46
+ # a notification is required the internal data structure is copied to
47
+ # prevent concurrency issues
48
+ #
49
+ class CopyOnNotifyObserverSet
50
+
51
+ def initialize
52
+ @mutex = Mutex.new
53
+ @observers = {}
54
+ end
55
+
56
+ # Adds an observer to this set, if a block is passed, the observer will be
57
+ # created by this method and no other params should be passed.
58
+ #
59
+ # @param [Object] observer
60
+ # the observer to add
61
+ # @param [Symbol] func
62
+ # the function to call on the observer during notification.
63
+ # Default is :update
64
+ #
65
+ # @return [Object]
66
+ # the added observer
67
+ #
68
+ def add_observer(observer = nil, func = :update, &block)
69
+ if observer.nil? && block.nil?
70
+ raise ArgumentError, 'should pass observer as a first argument or block'
71
+ elsif observer && block
72
+ raise ArgumentError, 'cannot provide both an observer and a block'
73
+ end
74
+
75
+ if block
76
+ observer = block
77
+ func = :call
78
+ end
79
+
80
+ begin
81
+ @mutex.lock
82
+ @observers[observer] = func
83
+ ensure
84
+ @mutex.unlock
85
+ end
86
+ observer
87
+ end
88
+
89
+ # @param [Object] observer the observer to remove
90
+ #
91
+ # @return [Object] the deleted observer
92
+ #
93
+ def delete_observer(observer)
94
+ @mutex.lock
95
+ @observers.delete(observer)
96
+ @mutex.unlock
97
+ observer
98
+ end
99
+
100
+ # Deletes all observers
101
+ #
102
+ # @return [CopyOnWriteObserverSet] self
103
+ #
104
+ def delete_observers
105
+ @mutex.lock
106
+ @observers.clear
107
+ @mutex.unlock
108
+ self
109
+ end
110
+
111
+ # @return [Integer] the observers count
112
+ #
113
+ def count_observers
114
+ @mutex.lock
115
+ result = @observers.count
116
+ @mutex.unlock
117
+ result
118
+ end
119
+
120
+ # Notifies all registered observers with optional args.
121
+ #
122
+ # @param [Object] args
123
+ # arguments to be passed to each observer
124
+ #
125
+ # @return [CopyOnWriteObserverSet] self
126
+ #
127
+ def notify_observers(*args, &block)
128
+ observers = duplicate_observers
129
+ notify_to(observers, *args, &block)
130
+ self
131
+ end
132
+
133
+ # Notifies all registered observers with optional args and deletes them.
134
+ #
135
+ # @param [Object] args
136
+ # arguments to be passed to each observer
137
+ #
138
+ # @return [CopyOnWriteObserverSet] self
139
+ #
140
+ def notify_and_delete_observers(*args, &block)
141
+ observers = duplicate_and_clear_observers
142
+ notify_to(observers, *args, &block)
143
+ self
144
+ end
145
+
146
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
147
+
148
+ def duplicate_and_clear_observers
149
+ @mutex.lock
150
+ observers = @observers.dup
151
+ @observers.clear
152
+ @mutex.unlock
153
+ observers
154
+ end
155
+
156
+ def duplicate_observers
157
+ @mutex.lock
158
+ observers = @observers.dup
159
+ @mutex.unlock
160
+ observers
161
+ end
162
+
163
+ def notify_to(observers, *args)
164
+ if block_given? && !args.empty?
165
+ raise ArgumentError, 'cannot give arguments and a block'
166
+ end
167
+ observers.each do |observer, function|
168
+ args = yield if block_given?
169
+ observer.send(function, *args)
170
+ end
171
+ end
172
+ end
173
+
174
+ # A thread safe observer set implemented using copy-on-write approach. Every
175
+ # time an observer is added or removed the whole internal data structure is
176
+ # duplicated and replaced with a new one.
177
+ #
178
+ class CopyOnWriteObserverSet
179
+
180
+ def initialize
181
+ @mutex = Mutex.new
182
+ @observers = {}
183
+ end
184
+
185
+ # Adds an observer to this set, if a block is passed, the observer will be
186
+ # created by this method and no other params should be passed.
187
+ #
188
+ # @param [Object] observer
189
+ # the observer to add
190
+ # @param [Symbol] func
191
+ # the function to call on the observer during notification
192
+ # Default is :update
193
+ # @return [Object]
194
+ # the added observer
195
+ #
196
+ def add_observer(observer = nil, func = :update, &block)
197
+ if observer.nil? && block.nil?
198
+ raise ArgumentError, 'should pass observer as a first argument or block'
199
+ elsif observer && block
200
+ raise ArgumentError, 'cannot provide both an observer and a block'
201
+ end
202
+
203
+ if block
204
+ observer = block
205
+ func = :call
206
+ end
207
+
208
+ begin
209
+ @mutex.lock
210
+ new_observers = @observers.dup
211
+ new_observers[observer] = func
212
+ @observers = new_observers
213
+ observer
214
+ ensure
215
+ @mutex.unlock
216
+ end
217
+ end
218
+
219
+ # @param [Object] observer the observer to remove
220
+ #
221
+ # @return [Object] the deleted observer
222
+ #
223
+ def delete_observer(observer)
224
+ @mutex.lock
225
+ new_observers = @observers.dup
226
+ new_observers.delete(observer)
227
+ @observers = new_observers
228
+ observer
229
+ ensure
230
+ @mutex.unlock
231
+ end
232
+
233
+ # Deletes all observers
234
+ #
235
+ # @return [CopyOnWriteObserverSet] self
236
+ #
237
+ def delete_observers
238
+ self.observers = {}
239
+ self
240
+ end
241
+
242
+
243
+ # @return [Integer] the observers count
244
+ #
245
+ def count_observers
246
+ observers.count
247
+ end
248
+
249
+ # Notifies all registered observers with optional args.
250
+ #
251
+ # @param [Object] args
252
+ # arguments to be passed to each observer
253
+ #
254
+ # @return [CopyOnWriteObserverSet] self
255
+ #
256
+ def notify_observers(*args, &block)
257
+ notify_to(observers, *args, &block)
258
+ self
259
+ end
260
+
261
+ # Notifies all registered observers with optional args and deletes them.
262
+ #
263
+ # @param [Object] args
264
+ # arguments to be passed to each observer
265
+ #
266
+ # @return [CopyOnWriteObserverSet] self
267
+ #
268
+ def notify_and_delete_observers(*args, &block)
269
+ old = clear_observers_and_return_old
270
+ notify_to(old, *args, &block)
271
+ self
272
+ end
273
+
274
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
275
+
276
+ def notify_to(observers, *args)
277
+ if block_given? && !args.empty?
278
+ raise ArgumentError, 'cannot give arguments and a block'
279
+ end
280
+ observers.each do |observer, function|
281
+ args = yield if block_given?
282
+ observer.send(function, *args)
283
+ end
284
+ end
285
+
286
+ def observers
287
+ @mutex.lock
288
+ @observers
289
+ ensure
290
+ @mutex.unlock
291
+ end
292
+
293
+ def observers=(new_set)
294
+ @mutex.lock
295
+ @observers = new_set
296
+ ensure
297
+ @mutex.unlock
298
+ end
299
+
300
+ def clear_observers_and_return_old
301
+ @mutex.lock
302
+ old_observers = @observers
303
+ @observers = {}
304
+ old_observers
305
+ ensure
306
+ @mutex.unlock
307
+ end
308
+ end
309
+ end
@@ -68,8 +68,10 @@ module MemStash
68
68
  #
69
69
  # stash.set('name') { 'Trigster' }
70
70
  # => "Trigster"
71
+ #
71
72
  # stash[:cash] = 'in the hash stash cache store'
72
73
  # => "in the hash stash cache store"
74
+ #
73
75
  # data = { id: 'trig', name: 'Trigster Jay', passwd: 'f00d' }
74
76
  # stash[:juser] = data
75
77
  # => {
data/lib/hoodie/utils.rb CHANGED
@@ -24,7 +24,9 @@ require 'time'
24
24
  module Hoodie
25
25
  module Utils
26
26
  def self.included(base)
27
- base.extend(ClassMethods)
27
+ include(ClassMethods)
28
+
29
+ base.send(:include, ClassMethods)
28
30
  end
29
31
  private_class_method :included
30
32
 
@@ -45,8 +47,8 @@ module Hoodie
45
47
  demodulize(self.class)
46
48
  end
47
49
 
48
- def caller_name
49
- caller_locations(2, 1).first.label
50
+ def caller_name(position = 0)
51
+ caller[position][/`.*'/][1..-2]
50
52
  end
51
53
 
52
54
  def demodulize(class_name_in_module)
@@ -95,173 +97,104 @@ module Hoodie
95
97
  end
96
98
  yield if block_given?
97
99
  end
98
- end # module ClassMethods
99
-
100
- # ============================================================================
101
-
102
- def callable(call_her)
103
- call_her.respond_to?(:call) ? call_her : lambda { call_her }
104
- end
105
-
106
- def camelize(underscored_word)
107
- underscored_word.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
108
- end
109
-
110
- def classify(table_name)
111
- camelize singularize(table_name.to_s.sub(/.*\./, ''))
112
- end
113
-
114
- def class_name
115
- demodulize(self.class)
116
- end
117
-
118
- def caller_name
119
- caller_locations(2, 1).first.label
120
- end
121
-
122
- def demodulize(class_name_in_module)
123
- class_name_in_module.to_s.sub(/^.*::/, '')
124
- end
125
-
126
- def pluralize(word)
127
- word.to_s.sub(/([^s])$/, '\1s')
128
- end
129
-
130
- def singularize(word)
131
- word.to_s.sub(/s$/, '').sub(/ie$/, 'y')
132
- end
133
-
134
- def underscore(camel_cased_word)
135
- word = camel_cased_word.to_s.dup
136
- word.gsub!(/::/, '/')
137
- word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
138
- word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
139
- word.tr! '-', '_'
140
- word.downcase!
141
- word
142
- end
143
-
144
- # Return the date and time in "HTTP-date" format as defined by RFC 7231.
145
- #
146
- # @return [Date,Time] in "HTTP-date" format
147
- def utc_httpdate
148
- Time.now.utc.httpdate
149
- end
150
100
 
151
- def request_id
152
- SecureRandom.uuid
153
- end
154
-
155
- def twenty_four_hours_ago
156
- Time.now - ( 60 * 60 * 24)
157
- end
158
-
159
- def verify_options(accepted, actual) # @private
160
- return unless debug || $DEBUG
161
- unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
162
- raise Croesus::Errors::UnknownOption,
163
- "\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" <<
164
- "Accepted options are: #{accepted.inspect}"
165
- end
166
- yield if block_given?
167
- end
168
-
169
- # Returns the columns and lines of the current tty.
170
- #
171
- # @return [Integer]
172
- # number of columns and lines of tty, returns [0, 0] if no tty is present.
173
- #
174
- # @api public
175
- def terminal_dimensions
176
- [0, 0] unless STDOUT.tty?
177
- [80, 40] if OS.windows?
178
-
179
- if ENV['COLUMNS'] && ENV['LINES']
180
- [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
181
- elsif ENV['TERM'] && command_in_path?('tput')
182
- [`tput cols`.to_i, `tput lines`.to_i]
183
- elsif command_in_path?('stty')
184
- `stty size`.scan(/\d+/).map {|s| s.to_i }
185
- else
101
+ # Returns the columns and lines of the current tty.
102
+ #
103
+ # @return [Integer]
104
+ # number of columns and lines of tty, returns [0, 0] if no tty present.
105
+ #
106
+ # @api public
107
+ def terminal_dimensions
108
+ [0, 0] unless STDOUT.tty?
109
+ [80, 40] if OS.windows?
110
+
111
+ if ENV['COLUMNS'] && ENV['LINES']
112
+ [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
113
+ elsif ENV['TERM'] && command_in_path?('tput')
114
+ [`tput cols`.to_i, `tput lines`.to_i]
115
+ elsif command_in_path?('stty')
116
+ `stty size`.scan(/\d+/).map {|s| s.to_i }
117
+ else
118
+ [0, 0]
119
+ end
120
+ rescue
186
121
  [0, 0]
187
122
  end
188
- rescue
189
- [0, 0]
190
- end
191
123
 
192
- # Checks in PATH returns true if the command is found
193
- def command_in_path?(command)
194
- found = ENV['PATH'].split(File::PATH_SEPARATOR).map do |p|
195
- File.exist?(File.join(p, command))
124
+ # Checks in PATH returns true if the command is found
125
+ def command_in_path?(command)
126
+ found = ENV['PATH'].split(File::PATH_SEPARATOR).map do |p|
127
+ File.exist?(File.join(p, command))
128
+ end
129
+ found.include?(true)
196
130
  end
197
- found.include?(true)
198
- end
199
131
 
200
- # Runs a code block, and retries it when an exception occurs. Should the
201
- # number of retries be reached without success, the last exception will be
202
- # raised.
203
- #
204
- # @param opts [Hash{Symbol => Value}]
205
- # @option opts [Fixnum] :tries
206
- # number of attempts to retry before raising the last exception
207
- # @option opts [Fixnum] :sleep
208
- # number of seconds to wait between retries, use lambda to exponentially
209
- # increasing delay between retries
210
- # @option opts [Array(Exception)] :on
211
- # the type of exception(s) to catch and retry on
212
- # @option opts [Regex] :matching
213
- # match based on the exception message
214
- # @option opts [Block] :ensure
215
- # ensure a block of code is executed, regardless of whether an exception
216
- # is raised
217
- #
218
- # @return [Block]
219
- #
220
- def retrier(opts = {}, &block)
221
- defaults = {
222
- tries: 2,
223
- sleep: 1,
224
- on: StandardError,
225
- matching: /.*/,
226
- :ensure => Proc.new {}
227
- }
228
-
229
- check_for_invalid_options(opts, defaults)
230
- defaults.merge!(opts)
132
+ # Runs a code block, and retries it when an exception occurs. Should the
133
+ # number of retries be reached without success, the last exception will be
134
+ # raised.
135
+ #
136
+ # @param opts [Hash{Symbol => Value}]
137
+ # @option opts [Fixnum] :tries
138
+ # number of attempts to retry before raising the last exception
139
+ # @option opts [Fixnum] :sleep
140
+ # number of seconds to wait between retries, use lambda to exponentially
141
+ # increasing delay between retries
142
+ # @option opts [Array(Exception)] :on
143
+ # the type of exception(s) to catch and retry on
144
+ # @option opts [Regex] :matching
145
+ # match based on the exception message
146
+ # @option opts [Block] :ensure
147
+ # ensure a block of code is executed, regardless of whether an exception
148
+ # is raised
149
+ #
150
+ # @return [Block]
151
+ #
152
+ def retrier(opts = {}, &block)
153
+ defaults = {
154
+ tries: 2,
155
+ sleep: 1,
156
+ on: StandardError,
157
+ matching: /.*/,
158
+ :ensure => Proc.new {}
159
+ }
231
160
 
232
- return if defaults[:tries] == 0
161
+ check_for_invalid_options(opts, defaults)
162
+ defaults.merge!(opts)
233
163
 
234
- on_exception, tries = [defaults[:on]].flatten, defaults[:tries]
235
- retries = 0
236
- retry_exception = nil
164
+ return if defaults[:tries] == 0
237
165
 
238
- begin
239
- yield retries, retry_exception
240
- rescue *on_exception => exception
241
- raise unless exception.message =~ defaults[:matching]
242
- raise if retries+1 >= defaults[:tries]
166
+ on_exception, tries = [defaults[:on]].flatten, defaults[:tries]
167
+ retries = 0
168
+ retry_exception = nil
243
169
 
244
- # Interrupt Exception could be raised while sleeping
245
170
  begin
246
- sleep defaults[:sleep].respond_to?(:call) ?
247
- defaults[:sleep].call(retries) : defaults[:sleep]
248
- rescue *on_exception
171
+ yield retries, retry_exception
172
+ rescue *on_exception => exception
173
+ raise unless exception.message =~ defaults[:matching]
174
+ raise if retries+1 >= defaults[:tries]
175
+
176
+ # Interrupt Exception could be raised while sleeping
177
+ begin
178
+ sleep defaults[:sleep].respond_to?(:call) ?
179
+ defaults[:sleep].call(retries) : defaults[:sleep]
180
+ rescue *on_exception
181
+ end
182
+
183
+ retries += 1
184
+ retry_exception = exception
185
+ retry
186
+ ensure
187
+ defaults[:ensure].call(retries)
249
188
  end
250
-
251
- retries += 1
252
- retry_exception = exception
253
- retry
254
- ensure
255
- defaults[:ensure].call(retries)
256
189
  end
257
- end
258
190
 
259
- private # P R O P R I E T À P R I V A T A Vietato L'accesso
191
+ private # P R O P R I E T À P R I V A T A Vietato L'accesso
260
192
 
261
- def check_for_invalid_options(custom_options, defaults)
262
- invalid_options = defaults.merge(custom_options).keys - defaults.keys
263
- raise ArgumentError.new('[Retrier] Invalid options: ' \
264
- "#{invalid_options.join(", ")}") unless invalid_options.empty?
193
+ def check_for_invalid_options(custom_options, defaults)
194
+ invalid_options = defaults.merge(custom_options).keys - defaults.keys
195
+ raise ArgumentError.new('[Retrier] Invalid options: ' \
196
+ "#{invalid_options.join(", ")}") unless invalid_options.empty?
197
+ end
265
198
  end
266
199
  end
267
200
  end
@@ -18,5 +18,5 @@
18
18
  #
19
19
 
20
20
  module Hoodie
21
- VERSION = '0.4.2'
21
+ VERSION = '0.4.3'
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoodie
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Harding
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-16 00:00:00.000000000 Z
11
+ date: 2014-12-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hitimes
@@ -28,84 +28,84 @@ dependencies:
28
28
  name: rubocop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.26.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
40
  version: 0.26.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 10.3.2
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
54
  version: 10.3.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: coveralls
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: 0.7.1
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
68
  version: 0.7.1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: 3.1.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 3.1.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: fuubar
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: 2.0.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: 2.0.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: timecop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: 0.7.1
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: 0.7.1
111
111
  description: A collection of hipster methods and hoodie tools to make even the nerdy
@@ -118,7 +118,7 @@ files:
118
118
  - ".gitattributes"
119
119
  - ".gitignore"
120
120
  - Gemfile
121
- - LICENSE
121
+ - LICENSE.md
122
122
  - README.md
123
123
  - Rakefile
124
124
  - hoodie.gemspec
@@ -128,6 +128,7 @@ files:
128
128
  - lib/hoodie/identity_map.rb
129
129
  - lib/hoodie/memoizable.rb
130
130
  - lib/hoodie/obfuscate.rb
131
+ - lib/hoodie/observable.rb
131
132
  - lib/hoodie/os.rb
132
133
  - lib/hoodie/rash.rb
133
134
  - lib/hoodie/stash.rb
@@ -156,8 +157,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
156
157
  version: '0'
157
158
  requirements: []
158
159
  rubyforge_project:
159
- rubygems_version: 2.2.2
160
+ rubygems_version: 2.4.1
160
161
  signing_key:
161
162
  specification_version: 4
162
163
  summary: Pragmatic hoodie concurrency hipster with ruby
163
164
  test_files: []
165
+ has_rdoc: