throttling 0.3.1 → 0.4.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3ed71179ebb7b627ce788a1ced69b28bba67f9d983614724390a95d6df97f2d1
4
+ data.tar.gz: cafd2ed60cf1758b5527d40d864aa8892d638631a9a95e977161227f34328eb0
5
+ SHA512:
6
+ metadata.gz: 3d98584e62d6d179e4f358946f7d4f179e56df6c4a30e338e0bcd8b65a59a2ff9d0cccc9ca392306f3412dab4b5c94d7b64225c949fd31626d8ba45ac8181455
7
+ data.tar.gz: 7bd43a024a5bfca1a9dcf4d05cf70a255233dd87382b9229f63d04c5ab06c081cd83a8d20b5be0586b5fb42d8293387ff3e41cbb03c8f137be6246fe946c2c11
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,4 @@
1
+ u�wn臙K�l �Rա ����J-cƬ|�2ݯm.D�M= h܂i�*j���y!��R3��H�M���Z!˥}e�aM]͢S� �&�
2
+ �M����e���no�!G0�e&?���o N��N�.��)�-�4������F5_���&`�zg�6F�c`����4)��um���Ŕ���NW�΁�j�ޛ�Q���G克�`J[
3
+ ,,�c�4S9��
4
+ �0!�<[K�ayjQ��>���[��x�Fn<�
data/CHANGELOG.md CHANGED
@@ -1,30 +1,42 @@
1
+ # Changelog
2
+
3
+ ## 0.4.1 (September 19, 2025)
4
+
5
+ - Multiple rexml fixes ([6](https://github.com/kpumuk/throttling/pull/6), [7](https://github.com/kpumuk/throttling/pull/7), [8](https://github.com/kpumuk/throttling/pull/8), [9](https://github.com/kpumuk/throttling/pull/9), [11](https://github.com/kpumuk/throttling/pull/11/))
6
+ - Use GitHub actions to build, sign and publish the gem ([11](https://github.com/kpumuk/throttling/pull/11/))
7
+
8
+ ## 0.4.0 (July 6, 2023)
9
+
10
+ - Bump minimum Ruby requirement to 2.7.0
11
+ - Updated codebase to match StandardRB style guide
12
+
1
13
  ## 0.3.1 (April 13, 2012)
2
14
 
3
15
  Features:
4
16
 
5
- - When limit is omitted, no limits will be enforced (`check` always returns true)
17
+ - When limit is omitted, no limits will be enforced (`check` always returns true)
6
18
 
7
19
  Bugfixes:
8
20
 
9
- - Fixed bug when action was allowed `limit + 1` times
10
- - When limit is 0, `check` should always return `false`
21
+ - Fixed bug when action was allowed `limit + 1` times
22
+ - When limit is 0, `check` should always return `false`
11
23
 
12
24
  ## 0.3.0 (April 13, 2012)
13
25
 
14
26
  Features:
15
27
 
16
- - Added ability to retrieve custom value based on number of actions performed in a period of time
28
+ - Added ability to retrieve custom value based on number of actions performed in a period of time
17
29
 
18
30
  ## 0.2.0 (April 12, 2012)
19
31
 
20
32
  Bugfixes:
21
33
 
22
- - Fixed bug when occurrences where increased for larger periods, when smaller ones did not pass
34
+ - Fixed bug when occurrences where increased for larger periods, when smaller ones did not pass
23
35
 
24
36
  ## 0.1.0 (April 12, 2012)
25
37
 
26
38
  Features:
27
39
 
28
- - Allows to throttle actions occurred in period of time
29
- - Allows to specify limits inline or in external configuration file
30
- - 100% test coverage
40
+ - Allows to throttle actions occurred in period of time
41
+ - Allows to specify limits inline or in external configuration file
42
+ - 100% test coverage
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in throttling.gemspec
4
4
  gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,88 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ throttling (0.4.1)
5
+ logger
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ast (2.4.3)
11
+ diff-lcs (1.6.2)
12
+ json (2.15.0)
13
+ language_server-protocol (3.17.0.5)
14
+ lint_roller (1.1.0)
15
+ logger (1.7.0)
16
+ parallel (1.27.0)
17
+ parser (3.3.9.0)
18
+ ast (~> 2.4.1)
19
+ racc
20
+ prism (1.5.1)
21
+ racc (1.8.1)
22
+ rainbow (3.1.1)
23
+ rake (13.3.0)
24
+ regexp_parser (2.11.3)
25
+ rspec (3.13.1)
26
+ rspec-core (~> 3.13.0)
27
+ rspec-expectations (~> 3.13.0)
28
+ rspec-mocks (~> 3.13.0)
29
+ rspec-core (3.13.5)
30
+ rspec-support (~> 3.13.0)
31
+ rspec-expectations (3.13.5)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.13.0)
34
+ rspec-mocks (3.13.5)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.13.0)
37
+ rspec-support (3.13.6)
38
+ rubocop (1.80.2)
39
+ json (~> 2.3)
40
+ language_server-protocol (~> 3.17.0.2)
41
+ lint_roller (~> 1.1.0)
42
+ parallel (~> 1.10)
43
+ parser (>= 3.3.0.2)
44
+ rainbow (>= 2.2.2, < 4.0)
45
+ regexp_parser (>= 2.9.3, < 3.0)
46
+ rubocop-ast (>= 1.46.0, < 2.0)
47
+ ruby-progressbar (~> 1.7)
48
+ unicode-display_width (>= 2.4.0, < 4.0)
49
+ rubocop-ast (1.47.1)
50
+ parser (>= 3.3.7.2)
51
+ prism (~> 1.4)
52
+ rubocop-performance (1.25.0)
53
+ lint_roller (~> 1.1)
54
+ rubocop (>= 1.75.0, < 2.0)
55
+ rubocop-ast (>= 1.38.0, < 2.0)
56
+ ruby-progressbar (1.13.0)
57
+ standard (1.51.1)
58
+ language_server-protocol (~> 3.17.0.2)
59
+ lint_roller (~> 1.0)
60
+ rubocop (~> 1.80.2)
61
+ standard-custom (~> 1.0.0)
62
+ standard-performance (~> 1.8)
63
+ standard-custom (1.0.2)
64
+ lint_roller (~> 1.0)
65
+ rubocop (~> 1.50)
66
+ standard-performance (1.8.0)
67
+ lint_roller (~> 1.1)
68
+ rubocop-performance (~> 1.25.0)
69
+ timecop (0.9.10)
70
+ unicode-display_width (3.2.0)
71
+ unicode-emoji (~> 4.1)
72
+ unicode-emoji (4.1.0)
73
+
74
+ PLATFORMS
75
+ arm64-darwin
76
+ arm64-linux
77
+ x86_64-darwin
78
+ x86_64-linux
79
+
80
+ DEPENDENCIES
81
+ rake (~> 13.0)
82
+ rspec (~> 3.13.0)
83
+ standard (~> 1.51.0)
84
+ throttling!
85
+ timecop (~> 0.9.6)
86
+
87
+ BUNDLED WITH
88
+ 2.3.26
data/README.md CHANGED
@@ -1,74 +1,79 @@
1
1
  # Throttling
2
2
 
3
- [![Travis-CI build status](https://secure.travis-ci.org/kpumuk/throttling.png)](http://travis-ci.org/kpumuk/throttling)
3
+ [![Tests](https://github.com/kpumuk/throttling/actions/workflows/tests.yml/badge.svg)](https://github.com/kpumuk/throttling/actions/workflows/tests.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/throttling.svg)](https://badge.fury.io/rb/throttling)
5
+ [![Gem Downloads](https://img.shields.io/gem/dt/throttling.svg)](https://badge.fury.io/rb/throttling)
6
+ [![Changelog](https://img.shields.io/badge/Changelog-latest-blue.svg)](https://github.com/kpumuk/throttling/blob/main/CHANGELOG.md)
4
7
 
5
8
  Throttling gem provides basic, but very powerful way to throttle various user actions in your application. Basically you can specify how many times some action could be performed over a specified period(s) of time.
6
9
 
7
10
  ## Installation
8
11
 
9
- Add this line to your application's Gemfile:
12
+ Add this line to your application's `Gemfile`:
10
13
 
11
- gem 'throttling'
14
+ ```ruby
15
+ gem "throttling"
16
+ ```
12
17
 
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
18
-
19
- $ gem install throttling
18
+ And run `bundle install` command.
20
19
 
21
20
  ## Configuration
22
21
 
23
- You can configure Throttling parameters by accessing attributes of `Throttling` module. Currently it supports only Memcached through `Rails.cache`.
22
+ You can configure Throttling parameters by accessing attributes of `Throttling` module. Currently it supports only Memcached and Redis through `Rails.cache`.
24
23
 
25
- Throttling.storage = Rails.cache
26
- Throttling.logger = Rails.logger
24
+ ```ruby
25
+ Throttling.storage = Rails.cache
26
+ Throttling.logger = Rails.logger
27
+ ```
27
28
 
28
29
  Throttling limits could be stored in a configuration file in `config/throttling.yml`. You can also specify another file to read limits from:
29
30
 
30
- Throttling.limits_config = "#{Rails.root}/config/throttling.yml"
31
+ ```ruby
32
+ Throttling.limits_config = "#{Rails.root}/config/throttling.yml"
33
+ ```
31
34
 
32
35
  The basic structure of the file is:
33
36
 
34
- user_signup:
35
- limit: 20
36
- period: 3600
37
-
38
- search_requests:
39
- minutely:
40
- limit: 300
41
- period: 600
42
- hourly:
43
- limit: 1000
44
- period: 3600
45
- daily:
46
- limit: 10000
47
- period: 86400
48
-
49
- request_priority:
50
- period: 86400
51
- default_value: 25
52
- values:
53
- high_priority:
54
- limit: 5
55
- value: 10
56
- medium_priority:
57
- limit: 15
58
- value: 15
59
- low_priority:
60
- limit: 100
61
- value: 20
37
+ ```yaml
38
+ user_signup:
39
+ limit: 20
40
+ period: 3600
41
+
42
+ search_requests:
43
+ minutely:
44
+ limit: 300
45
+ period: 600
46
+ hourly:
47
+ limit: 1000
48
+ period: 3600
49
+ daily:
50
+ limit: 10000
51
+ period: 86400
52
+
53
+ request_priority:
54
+ period: 86400
55
+ default_value: 25
56
+ values:
57
+ high_priority:
58
+ limit: 5
59
+ value: 10
60
+ medium_priority:
61
+ limit: 15
62
+ value: 15
63
+ low_priority:
64
+ limit: 100
65
+ value: 20
66
+ ```
62
67
 
63
68
  This example covers three different scenarios:
64
69
 
65
- 1. Single period. In this case only 20 actions will be allowed in a period of
70
+ 1. **Single period**. In this case only 20 actions will be allowed in a period of
66
71
  one hour (3600 seconds).
67
72
 
68
- 2. Multiple periods. Action will be allowed to perform 300 times in 10 minutes,
73
+ 2. **Multiple periods**. Action will be allowed to perform 300 times in 10 minutes,
69
74
  1000 times an hour, and 10000 times a day.
70
75
 
71
- 3. This special case covers following scenario: based on the number of actions,
76
+ 3. **Complex scenario**. This special case covers following scenario: based on the number of actions,
72
77
  it returns a value, or default value when largest limit is reached. In this
73
78
  case it will return 10, when there were 5 or less requests (including current one),
74
79
  15 for up to 15 requests, 20 for up to 100 requests, and 25 when there were
@@ -76,110 +81,132 @@ This example covers three different scenarios:
76
81
 
77
82
  You can also specify limits as a Hash:
78
83
 
79
- Throttling.limits = {
80
- :user_signup => {
81
- :limit => 20,
82
- :period => 3600
83
- },
84
- :search_requests => {
85
- :minutely => {
86
- :limit => 20,
87
- :period => 3600
88
- },
89
- :hourly => {
90
- :limit => 1000,
91
- :period => 3600
92
- },
93
- :daily =>
94
- :limit => 10000,
95
- :period => 86400
96
- }
97
- }
84
+ ```ruby
85
+ Throttling.limits = {
86
+ user_signup: {
87
+ limit: 20,
88
+ period: 3600
89
+ },
90
+ search_requests: {
91
+ minutely: {
92
+ limit: 20,
93
+ period: 3600
94
+ },
95
+ hourly: {
96
+ limit: 1000,
97
+ period: 3600
98
+ },
99
+ daily: {
100
+ limit: 10000,
101
+ period: 86400
98
102
  }
103
+ }
104
+ }
105
+ ```
99
106
 
100
107
  You can completely disable throttling by setting `enabled` to `false`:
101
108
 
102
- Throttling.enabled = false
109
+ ```ruby
110
+ Throttling.enabled = false
111
+ ```
103
112
 
104
113
  ## Usage
105
114
 
106
115
  The basic usage of Throttling gem is following:
107
116
 
108
- Throttling.for(:user_signup).check(:user_id, current_user.id) do
109
- # Do your stuff here
110
- end
117
+ ```ruby
118
+ Throttling.for(:user_signup).check(:user_id, current_user.id) do
119
+ # Do your stuff here
120
+ end
111
121
 
112
- if Throttling.for(:user_signup).check(:user_id, current_user.id)
113
- # Action allowed
114
- else
115
- # Action denied
116
- end
122
+ if Throttling.for(:user_signup).check(:user_id, current_user.id)
123
+ # Action allowed
124
+ else
125
+ # Action denied
126
+ end
127
+ ```
117
128
 
118
129
  For convenience, there are some simplified methods:
119
130
 
120
- Throttling.for(:user_signup).check_ip(request.remote_ip)
121
- Throttling.for(:user_signup).check_user_id(current_user.id)
131
+ ```ruby
132
+ Throttling.for(:user_signup).check_ip(request.remote_ip)
133
+ Throttling.for(:user_signup).check_user_id(current_user.id)
134
+ ```
122
135
 
123
136
  You can add more helpers like this:
124
137
 
125
- Throttling::Base.class_eval do
126
- def check_user_id_and_document_id(user_id, doc_id)
127
- check("user_id:doc_id", "#{user_id}:#{doc_id}")
128
- end
129
- end
138
+ ```ruby
139
+ Throttling::Base.class_eval do
140
+ def check_user_id_and_document_id(user_id, doc_id)
141
+ check("user_id:doc_id", "#{user_id}:#{doc_id}")
142
+ end
143
+ end
144
+ ```
130
145
 
131
146
  ## Use cases
132
147
 
133
148
  ### Limiting number of sign-ups
134
149
 
135
- user_signup:
136
- limit: 20
137
- period: 3600
150
+ ```yaml
151
+ user_signup:
152
+ limit: 20
153
+ period: 3600
154
+ ```
138
155
 
139
156
  Limit the number of sign-ups to 20 per hour per IP address:
140
157
 
141
- Throttling.for('user_signup').check_ip(request.remote_ip)
158
+ ```ruby
159
+ Throttling.for("user_signup").check_ip(request.remote_ip)
160
+ ```
142
161
 
143
162
  ### Limiting number of document uploads
144
163
 
145
- document_uploads:
146
- minutely:
147
- limit: 5
148
- period: 600
149
- hourly:
150
- limit: 10
151
- period: 3600
152
- daily:
153
- limit: 50
154
- period: 86400
164
+ ```yaml
165
+ document_uploads:
166
+ minutely:
167
+ limit: 5
168
+ period: 600
169
+ hourly:
170
+ limit: 10
171
+ period: 3600
172
+ daily:
173
+ limit: 50
174
+ period: 86400
175
+ ```
155
176
 
156
177
  In this case user will be allowed to upload 5 documents in 10 minutes, 10 documents
157
178
  in an hour, or 50 documents a day:
158
179
 
159
- Throttling.for('document_uploads').check_user_id(current_user.id)
180
+ ```ruby
181
+ Throttling.for("document_uploads").check_user_id(current_user.id)
182
+ ```
160
183
 
161
184
  ### Prioritizing uploads based on number of uploads
162
185
 
163
- document_priorities:
164
- period: 86400
165
- default_value: 25
166
- values:
167
- high_priority:
168
- limit: 5
169
- value: 10
170
- medium_priority:
171
- limit: 15
172
- value: 15
173
- low_priority:
174
- limit: 100
175
- value: 20
186
+ ```yaml
187
+ document_priorities:
188
+ period: 86400
189
+ default_value: 25
190
+ values:
191
+ high_priority:
192
+ limit: 5
193
+ value: 10
194
+ medium_priority:
195
+ limit: 15
196
+ value: 15
197
+ low_priority:
198
+ limit: 100
199
+ value: 20
200
+ ```
176
201
 
177
202
  All documents could be prioritized based on the number of uploads: if user uploads
178
203
  less than 5 documents a day, they all will have priority 10. Next 10 documents
179
204
  (first five keep their original priority) will receive priority 15. Documents
180
205
  16 to 100 will get priority 20, and everything else will get priority 25.
181
206
 
182
- Throttling.for('document_priorities').check_user_id(current_user.id)
207
+ ```ruby
208
+ Throttling.for("document_priorities").check_user_id(current_user.id)
209
+ ```
183
210
 
184
211
  ## Contributing
185
212
 
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
3
 
4
- require 'rspec/core/rake_task'
4
+ require "rspec/core/rake_task"
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- task :test => :spec
8
- task :default => :spec
7
+ task test: :spec
8
+ task default: :spec
data/certs/kpumuk.pem ADDED
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MQ8wDQYDVQQDDAZrcHVt
3
+ dWsxFjAUBgoJkiaJk/IsZAEZFgZrcHVtdWsxFDASBgoJkiaJk/IsZAEZFgRpbmZv
4
+ MB4XDTI1MDkyOTE1MDM1M1oXDTI2MDkyOTE1MDM1M1owPzEPMA0GA1UEAwwGa3B1
5
+ bXVrMRYwFAYKCZImiZPyLGQBGRYGa3B1bXVrMRQwEgYKCZImiZPyLGQBGRYEaW5m
6
+ bzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALw2YroZc+IT+rs8NuPu
7
+ c13DelrxrpAgPEu1zuRb3l7WaHRNWA4TyS8Z6Aa1G2O+FdUZNMW1n7IwP/QMJ9Mz
8
+ ahRBiTmhik5kasJ9s0h1lq5/hZiycm0o5OtGioUzCkvk+UEMpzMHbLmVSZCzYciy
9
+ NDRDbXB0rLLu1eJk+gKgn6Qf5vj93h1w28BdWdaA7YegtbmipZ+pjmzCQAfPActT
10
+ 6uXHG4dSo7Lz9jiFRI5dUizFbGXcRqkQ2b5AB8FFmfcvbqERvzQKBICnybjsKP0N
11
+ pJ3vGgO2sh5GvJFOPk1Vlur2nX9ZFznPEP1CEAQ+NFrmKRt355Z5sgOkAojSGnIL
12
+ /1sCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFPa4
13
+ VFc1YOlV1u/7EGTwMCAk8YE9MB0GA1UdEQQWMBSBEmtwdW11a0BrcHVtdWsuaW5m
14
+ bzAdBgNVHRIEFjAUgRJrcHVtdWtAa3B1bXVrLmluZm8wDQYJKoZIhvcNAQELBQAD
15
+ ggEBAFz/6+efHFEomTCA8V/eMpzaMkbj04cTmFxm28KiUO1F4vgbSIBx0bsMoJkH
16
+ KI956sPVVJMykwOdDUhRWBrHOVTBCGdkYWdb38KQKfwtkdGd8b/Afrxs5GuPME9r
17
+ TdfDc1aXCAPdLCajhpmuzfa1g8/W7ORdxwNQidYSSPJ5OvcAGSfxTHJsFseHjrBK
18
+ 9hdoXZgqc4a5defxoOZFD9Im9AUwFqwR8njCBST6FbCGmHIYNHj2hxbwrU/1I2Kg
19
+ pPzkBOwQl2p1ykAEUe7cwoqJcO+1rPeTHjudNqhOfc3VnMA8A7uXOkTtYNVhvApn
20
+ oW4hE/8SnZkQm8jzdi0iX9nWxo8=
21
+ -----END CERTIFICATE-----
@@ -15,7 +15,7 @@ module Throttling
15
15
  if @limits[:values]
16
16
  @limits[:values] = @limits[:values].sort_by { |name, params| params && params[:limit] }
17
17
  end
18
- @limits = [[ 'global', @limits ]]
18
+ @limits = [["global", @limits]]
19
19
  else
20
20
  @limits = @limits.sort_by { |name, params| params && params[:period] }
21
21
  end
@@ -35,7 +35,7 @@ module Throttling
35
35
 
36
36
  limits.each do |period_name, params|
37
37
  period = params[:period].to_i
38
- limit = params[:limit].nil? ? nil : params[:limit].to_i
38
+ limit = params[:limit]&.to_i
39
39
  values = params[:values]
40
40
 
41
41
  raise ArgumentError, "Invalid or no 'period' parameter in the limits[#{action}][#{period_name}] config: #{limit.inspect}" if period < 1
@@ -44,7 +44,7 @@ module Throttling
44
44
  key = hits_store_key(check_type, check_value, period_name, period)
45
45
 
46
46
  # Retrieve current value
47
- hits = Throttling.storage.fetch(key, :expires_in => hits_store_ttl(period), :raw => true) { '0' }.to_i
47
+ hits = Throttling.storage.fetch(key, expires_in: hits_store_ttl(period), raw: true) { "0" }.to_i
48
48
 
49
49
  if values
50
50
  value = params[:default_value] || false
@@ -54,16 +54,16 @@ module Throttling
54
54
  break
55
55
  end
56
56
  end
57
- else
57
+ elsif !limit.nil? && hits >= limit
58
58
  # Over limit?
59
- return false if !limit.nil? && hits >= limit
59
+ return false
60
60
  end
61
61
 
62
62
  Throttling.storage.increment(key) if auto_increment
63
63
  return value if values
64
64
  end
65
65
 
66
- return true
66
+ true
67
67
  end
68
68
 
69
69
  private
@@ -15,7 +15,7 @@ module Throttling
15
15
  super()
16
16
  update(constructor)
17
17
  else
18
- super(constructor)
18
+ super
19
19
  end
20
20
  end
21
21
 
@@ -84,7 +84,7 @@ module Throttling
84
84
  # hash.values_at("a", "b") # => ["x", "y"]
85
85
  #
86
86
  def values_at(*indices)
87
- indices.collect {|key| self[convert_key(key)]}
87
+ indices.collect { |key| self[convert_key(key)] }
88
88
  end
89
89
 
90
90
  # Returns an exact copy of the hash.
@@ -95,13 +95,13 @@ module Throttling
95
95
  # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
96
96
  # Does not overwrite the existing hash.
97
97
  def merge(hash)
98
- self.dup.update(hash)
98
+ dup.update(hash)
99
99
  end
100
100
 
101
101
  # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
102
102
  # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
103
103
  def reverse_merge(other_hash)
104
- super other_hash.with_indifferent_access
104
+ super(other_hash.with_indifferent_access)
105
105
  end
106
106
 
107
107
  # Removes a specified key from the hash.
@@ -109,9 +109,17 @@ module Throttling
109
109
  super(convert_key(key))
110
110
  end
111
111
 
112
- def stringify_keys!; self end
113
- def symbolize_keys!; self end
114
- def to_options!; self end
112
+ def stringify_keys!
113
+ self
114
+ end
115
+
116
+ def symbolize_keys!
117
+ self
118
+ end
119
+
120
+ def to_options!
121
+ self
122
+ end
115
123
 
116
124
  # Convert to a Hash with String keys.
117
125
  def to_hash
@@ -119,31 +127,32 @@ module Throttling
119
127
  end
120
128
 
121
129
  protected
122
- def convert_key(key)
123
- key.kind_of?(Symbol) ? key.to_s : key
124
- end
125
130
 
126
- def convert_value(value)
127
- case value
128
- when Hash
129
- value.with_indifferent_access
130
- when Array
131
- value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
132
- else
133
- value
134
- end
131
+ def convert_key(key)
132
+ key.is_a?(Symbol) ? key.to_s : key
133
+ end
134
+
135
+ def convert_value(value)
136
+ case value
137
+ when Hash
138
+ value.with_indifferent_access
139
+ when Array
140
+ value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
141
+ else
142
+ value
135
143
  end
144
+ end
136
145
  end
137
146
 
138
- module HashIndifferentAccess #:nodoc:
147
+ module HashIndifferentAccess # :nodoc:
139
148
  def with_indifferent_access
140
149
  hash = HashWithIndifferentAccess.new(self)
141
- hash.default = self.default
150
+ hash.default = default
142
151
  hash
143
152
  end
144
153
  end
145
154
 
146
- class ::Hash #:nodoc:
155
+ class ::Hash # :nodoc:
147
156
  unless respond_to?(:with_indifferent_access)
148
157
  include Throttling::HashIndifferentAccess
149
158
  end
@@ -1,3 +1,3 @@
1
1
  module Throttling
2
- VERSION = '0.3.1'
2
+ VERSION = "0.4.1"
3
3
  end